Generalize getting tab offset and fix tabs in selection

This commit is contained in:
Matúš Púll 2025-05-29 19:08:33 +02:00
parent 7391e5085a
commit c162473683
4 changed files with 25 additions and 16 deletions

View file

@ -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:

View file

@ -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<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

View file

@ -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;
}

View file

@ -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