diff --git a/editor.cpp b/editor.cpp index 1ca01d7..76983ba 100644 --- a/editor.cpp +++ b/editor.cpp @@ -185,6 +185,7 @@ bool Editor::take_action() { break; case 'i': mode = INSERT; + current_insert = file.get_line(file_offset + cur.r, 0); break; case 'v': mode = SELECT; @@ -223,40 +224,36 @@ bool Editor::take_action() { } break; case INSERT: - // TODO remake insert mode for better undo switch(ch) { case ESC: mode = NORMAL; - // Change current row into current_insert TODO - print_current_line(); + file.set_line(cur.r, current_insert); + print_text(cur.r, Treap::substitute_tabs(current_insert)); + current_insert = ""; break; case BS: - // Modify current_insert TODO if(cur.c > 0) { cur.c -= 1; - file.remove(cur + file_offset); + current_insert.erase(cur.c - Treap::get_tab_offset(cur.c, current_insert), 1); } - print_current_line(); + print_text(cur.r, Treap::substitute_tabs(current_insert)); break; case ENTER: - // Modify current_insert and update TODO + file.set_line(cur.r, current_insert); file.split_line(cur + file_offset); + cur.r++; cur.c = 0; move(cur); + current_insert = file.get_line(cur.r); print_file(file_offset); - cur.r++; - cur.c = 0; - move(cur); break; case '\t': - // Modify current_insert TODO - file.insert(cur + file_offset, "\t"); + current_insert.insert(cur.c - Treap::get_tab_offset(cur.c, current_insert), "\t"); cur.c += TAB_SIZE - (cur.c % TAB_SIZE); - print_current_line(); + print_text(cur.r, Treap::substitute_tabs(current_insert)); break; default: - // Modify current_insert TODO - file.insert(cur + file_offset, string(1, ch)); + current_insert.insert(cur.c - Treap::get_tab_offset(cur.c, current_insert), string(1, ch)); cur.c += 1; - print_current_line(); + print_text(cur.r, Treap::substitute_tabs(current_insert)); break; } break; diff --git a/everything.hpp b/everything.hpp index 4dab148..125ecd2 100644 --- a/everything.hpp +++ b/everything.hpp @@ -40,8 +40,11 @@ class Treap { line* find(count_type k); count_type bulk_find(vector *vec, line *l, count_type k, count_type count); - string substitute_tabs(string s); public: + static string substitute_tabs(string s); + static count_type get_tab_offset(count_type c, string text); + count_type get_tab_offset(position p) { return get_tab_offset(p.c, get_line(p.r, 0)); } + // General operations Treap() { srand(120); root = nullptr; } count_type size() { return get_size(root); } @@ -50,11 +53,11 @@ public: // Line operations string get_line(count_type r, bool substitute_tab = 1); vector bulk_get_line(count_type r, count_type count); - count_type get_tab_offset(position p); - void split_line(position p); + void split_line(position p); void insert(count_type k, string s); void remove(count_type k); + void set_line(count_type k, string s) { find(k)->text = s; } // Substring operations void insert(position p, string t); diff --git a/treap.cpp b/treap.cpp index 4d0bc90..d14e82e 100644 --- a/treap.cpp +++ b/treap.cpp @@ -19,6 +19,17 @@ string Treap::substitute_tabs(string s) { } return ret; } +// Get how much tabs changed position on a row +count_type Treap::get_tab_offset(count_type c, string text) { + count_type tab_offset = 0; + for(count_type i = 0; i + tab_offset < c; ++i) { + if(text[i] == '\t') + tab_offset += TAB_SIZE - (i+tab_offset) % TAB_SIZE - 1; + if(i + tab_offset > c) + tab_offset -= i + tab_offset - c; + } + return tab_offset; +} // Split treap by k-th element two_lines Treap::split(line *l, count_type k) { @@ -147,18 +158,6 @@ vector Treap::bulk_get_line(count_type r, count_type count) { return ret; } -// Get how much tabs changed position on a row -count_type Treap::get_tab_offset(position p) { - count_type tab_offset = 0; - string line = get_line(p.r, false); - for(count_type i = 0; i + tab_offset < p.c; ++i) { - if(line[i] == '\t') - tab_offset += TAB_SIZE - (i+tab_offset) % TAB_SIZE - 1; - if(i + tab_offset > p.c) - tab_offset -= i + tab_offset - p.c; - } - return tab_offset; -} void Treap::insert(position p, string t) { find(p.r)->text.insert(p.c-get_tab_offset(p), t); }