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;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
current_insert.insert(cur.c - get_tab_offset(cur.c, current_insert), "\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));
|
print_text(cur.r, substitute_tabs(current_insert));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -17,17 +17,20 @@ struct position {
|
||||||
};
|
};
|
||||||
|
|
||||||
// String utilities
|
// String utilities
|
||||||
|
count_type get_tab_length(count_type c);
|
||||||
string substitute_tabs(string s);
|
string substitute_tabs(string s);
|
||||||
count_type get_tab_offset(count_type c, string text);
|
count_type get_tab_offset(count_type c, string text);
|
||||||
|
|
||||||
//// Treap
|
//// Treap
|
||||||
|
|
||||||
// Treap node representation of a line
|
// Treap node representation of a line
|
||||||
struct line {
|
struct line {
|
||||||
count_type priority, size;
|
count_type priority, size; // Treap innards
|
||||||
string text;
|
string text; // Content
|
||||||
line *left, *right;
|
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;
|
typedef std::pair<line*, line*> two_lines;
|
||||||
|
|
||||||
|
@ -43,19 +46,19 @@ class Treap {
|
||||||
line* find(line *l, count_type k);
|
line* find(line *l, count_type k);
|
||||||
line* find(count_type k);
|
line* find(count_type k);
|
||||||
count_type bulk_find(vector<string> *vec, line *l, count_type k, count_type count);
|
count_type bulk_find(vector<string> *vec, line *l, count_type k, count_type count);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
count_type get_tab_offset(position p) { return ::get_tab_offset(p.c, get_line(p.r, 0)); }
|
|
||||||
|
|
||||||
// General operations
|
// General operations
|
||||||
Treap() { srand(120); root = nullptr; }
|
Treap() { srand(120); root = nullptr; }
|
||||||
count_type size() { return get_size(root); }
|
count_type size() { return get_size(root); }
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
// Line operations
|
// Line get operations
|
||||||
string get_line(count_type r, bool substitute_tab = 1);
|
string get_line(count_type r, bool substitute_tab = 1);
|
||||||
vector<string> bulk_get_line(count_type r, count_type count);
|
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 split_line(position p);
|
||||||
void insert(count_type k, string s);
|
void insert(count_type k, string s);
|
||||||
void remove(count_type k);
|
void remove(count_type k);
|
||||||
|
@ -69,7 +72,8 @@ public:
|
||||||
//// Selection
|
//// Selection
|
||||||
class Selection {
|
class Selection {
|
||||||
Treap *file;
|
Treap *file;
|
||||||
Treap content; // selection
|
Treap content;
|
||||||
|
|
||||||
template <typename F, typename G>
|
template <typename F, typename G>
|
||||||
void apply_on_selection(position p, F func, G func2);
|
void apply_on_selection(position p, F func, G func2);
|
||||||
public:
|
public:
|
||||||
|
@ -105,6 +109,7 @@ class Editor{
|
||||||
Selection selection;
|
Selection selection;
|
||||||
string current_insert;
|
string current_insert;
|
||||||
|
|
||||||
|
// Write to file
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
// Printing
|
// Printing
|
||||||
|
|
10
main.cpp
10
main.cpp
|
@ -1,12 +1,16 @@
|
||||||
#include "everything.hpp"
|
#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
|
// Substitute tab characters into regular tabs
|
||||||
string substitute_tabs(string s) {
|
string substitute_tabs(string s) {
|
||||||
string ret = "";
|
string ret = "";
|
||||||
for(count_type i = 0; i < s.size(); ++i) {
|
for(count_type i = 0; i < s.size(); ++i) {
|
||||||
if(s[i] == '\t') {
|
if(s[i] == '\t') {
|
||||||
ret += ' ';
|
count_type this_tab_length = get_tab_length(ret.size());
|
||||||
while(ret.size() % TAB_SIZE != 0)
|
for(count_type j = 0; j < this_tab_length; j++)
|
||||||
ret += ' ';
|
ret += ' ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -19,7 +23,7 @@ count_type get_tab_offset(count_type c, string text) {
|
||||||
count_type tab_offset = 0;
|
count_type tab_offset = 0;
|
||||||
for(count_type i = 0; i + tab_offset < c; ++i) {
|
for(count_type i = 0; i + tab_offset < c; ++i) {
|
||||||
if(text[i] == '\t')
|
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)
|
if(i + tab_offset > c)
|
||||||
tab_offset -= 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) {
|
void Selection::remove_selection(position p) {
|
||||||
apply_on_selection(p,
|
apply_on_selection(p,
|
||||||
[](count_type r, Treap *file, Treap *sel){ file->remove(r); },
|
[](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
|
// Copying selection
|
||||||
void Selection::copy_selection(position p) {
|
void Selection::copy_selection(position p) {
|
||||||
apply_on_selection(p,
|
apply_on_selection(p,
|
||||||
[](count_type r, Treap *file, Treap *sel){ sel->insert(0, file->get_line(r)); },
|
[](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).substr(start_c, size)); }
|
[](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
|
// Pasting selection
|
||||||
|
|
Loading…
Reference in a new issue