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

View file

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

View file

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

View file

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