diff --git a/editor.cpp b/editor.cpp index 35de0fc..75aa5fd 100644 --- a/editor.cpp +++ b/editor.cpp @@ -247,7 +247,7 @@ bool Editor::take_action() { break; case '\t': current_insert.insert(cur.c - get_tab_offset(cur.c, current_insert), "\t"); - cur.c += TAB_SIZE - (cur.c % TAB_SIZE); + cur.c += get_tab_length(cur.c); print_text(cur.r, substitute_tabs(current_insert)); break; default: diff --git a/everything.hpp b/everything.hpp index 414958f..5f86413 100644 --- a/everything.hpp +++ b/everything.hpp @@ -17,17 +17,20 @@ struct position { }; // String utilities +count_type get_tab_length(count_type c); string substitute_tabs(string s); count_type get_tab_offset(count_type c, string text); -//// Treap +//// Treap + // Treap node representation of a line struct line { - count_type priority, size; - string text; - line *left, *right; + count_type priority, size; // Treap innards + string text; // Content + line *left, *right; // Sons - line(count_type _p, string _t) : priority(_p), text(_t), size(1), left(nullptr), right(nullptr) {} + line(count_type _p, string _t) : + priority(_p), text(_t), size(1), left(nullptr), right(nullptr) {} }; typedef std::pair two_lines; @@ -43,19 +46,19 @@ class Treap { line* find(line *l, count_type k); line* find(count_type k); count_type bulk_find(vector *vec, line *l, count_type k, count_type count); - public: - 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); } void clear(); - // Line operations + // Line get 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) { return ::get_tab_offset(p.c, get_line(p.r, 0)); } + // Line set operations void split_line(position p); void insert(count_type k, string s); void remove(count_type k); @@ -69,7 +72,8 @@ public: //// Selection class Selection { Treap *file; - Treap content; // selection + Treap content; + template void apply_on_selection(position p, F func, G func2); public: @@ -105,6 +109,7 @@ class Editor{ Selection selection; string current_insert; + // Write to file void save(); // Printing diff --git a/main.cpp b/main.cpp index c150a6a..e0bbb6f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,16 @@ #include "everything.hpp" +// Get tab length at a certain position +count_type get_tab_length(count_type c) { + return TAB_SIZE - (c % TAB_SIZE); +} // Substitute tab characters into regular tabs string substitute_tabs(string s) { string ret = ""; for(count_type i = 0; i < s.size(); ++i) { if(s[i] == '\t') { - ret += ' '; - while(ret.size() % TAB_SIZE != 0) + count_type this_tab_length = get_tab_length(ret.size()); + for(count_type j = 0; j < this_tab_length; j++) ret += ' '; } else @@ -19,7 +23,7 @@ count_type 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; + tab_offset += get_tab_length(i+tab_offset) - 1; if(i + tab_offset > c) tab_offset -= i + tab_offset - c; } diff --git a/selection.cpp b/selection.cpp index 47ed586..551f680 100644 --- a/selection.cpp +++ b/selection.cpp @@ -28,14 +28,14 @@ void Selection::apply_on_selection(position p, F func, G func2) { void Selection::remove_selection(position p) { apply_on_selection(p, [](count_type r, Treap *file, Treap *sel){ file->remove(r); }, - [](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { file->remove({r, start_c}, size); } + [](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { file->remove({r, start_c-file->get_tab_offset({r, start_c})}, size); } ); } // Copying selection void Selection::copy_selection(position p) { apply_on_selection(p, - [](count_type r, Treap *file, Treap *sel){ sel->insert(0, file->get_line(r)); }, - [](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { sel->insert(0, file->get_line(r).substr(start_c, size)); } + [](count_type r, Treap *file, Treap *sel){ sel->insert(0, file->get_line(r, false)); }, + [](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { sel->insert(0, file->get_line(r, false).substr(start_c - file->get_tab_offset({r, start_c}), size)); } ); } // Pasting selection