Generalize getting tab offset and fix tabs in selection
This commit is contained in:
parent
7391e5085a
commit
c162473683
4 changed files with 25 additions and 16 deletions
|
@ -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:
|
||||
|
|
|
@ -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 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<line*, line*> 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<string> *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<string> 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 <typename F, typename G>
|
||||
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
|
||||
|
|
10
main.cpp
10
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue