Unite everything with file_offset

This commit is contained in:
Matúš Púll 2025-04-16 21:12:54 +02:00
parent a9bc74264d
commit fe62172682
2 changed files with 50 additions and 44 deletions

View file

@ -13,7 +13,10 @@ using std::string;
#define adds(s) addstr(s.c_str()) #define adds(s) addstr(s.c_str())
enum mode_type { INSERT, NORMAL, SELECT }; enum mode_type { INSERT, NORMAL, SELECT };
struct position { count_type r, c; }; struct position {
count_type r, c;
position operator+(count_type offset) { return {r + offset, c}; }
};
// Global variables // Global variables
treap file; treap file;
@ -23,23 +26,24 @@ position clp;
treap selection; treap selection;
// Accessing the file // Accessing the file
string get_line(count_type r, bool clean = true) { string get_line(count_type r, bool substitute_tab = true) {
string line = (*file.find(file_offset+r)).text; string line = file.get(r);
if(!clean) if(!substitute_tab)
return line; return line;
for(count_type i = 0; i < line.size(); ++i) for(count_type i = 0; i < line.size(); ++i)
if(line[i] == '\t') if(line[i] == '\t')
line[i] = ' '; line[i] = ' ';
return line; return line;
} }
void set(position p, char ch) { file.find(file_offset+p.r)->text[p.c] = ch; } void set(position p, char ch) { file.find(p.r)->text[p.c] = ch; }
void new_line(count_type r, string text = "") { file.insert(file_offset+r, text); } void new_line(count_type r, string text = "") { file.insert(r, text); }
void insert(position p, string t) { file.find(file_offset+p.r)->text.insert(p.c, t); } void insert(position p, string t) { file.find(p.r)->text.insert(p.c, t); }
void insert(position p, char ch) { insert(p, string{ch}); } void insert(position p, char ch) { insert(p, string{ch}); }
void remove(position p, count_type len=1) { file.find(p.r)->text.erase(p.c,len); }
void remove(count_type r) { file.remove(r); }
void append(string t) { file.append(t); } void append(string t) { file.append(t); }
void remove(position p, count_type len=1) { file.find(file_offset+p.r)->text.erase(p.c,len); }
void remove(count_type r) { file.remove(file_offset+r); }
// Taking user input
count_type get_number() { count_type get_number() {
char ch = '0'; char ch = '0';
string s = ""; string s = "";
@ -68,26 +72,26 @@ bool save(string filename) {
return 1; return 1;
for(count_type i = 0; i < file.size(); ++i) for(count_type i = 0; i < file.size(); ++i)
outfile << get_line(i-file_offset, 0) << std::endl; outfile << get_line(i, 0) << std::endl;
return 0; return 0;
} }
// Clear line // Clear line
void clear_line(count_type r) { void clear_line(count_type r) {
move(r, 0); move(r - file_offset, 0);
clrtoeol(); clrtoeol();
} }
// Print line // Print line
void print_line(count_type r) { void print_line(count_type r) {
clear_line(r); clear_line(r);
move(r, 0); move(r - file_offset, 0);
adds(get_line(r)); adds(get_line(r));
} }
// Print file content // Print file content
void print_file(count_type start = 0) { void print_file(count_type start = 0) {
for(count_type i = start; i < LINES; i++) for(count_type i = start; i < file_offset + LINES; i++)
if(file_offset+i < file.size()) if(i < file.size())
print_line(i); print_line(i);
else else
clear_line(i); clear_line(i);
@ -101,9 +105,9 @@ void split_line(position p) {
} }
// Copying // Copying
void copy_selection() { void copy_selection(position p = cur + file_offset) {
// Determine first and last selected position // Determine first and last selected position
position start = cur, end = clp; position start = p, end = clp;
if(clp.r < cur.r || (clp.r == cur.r && clp.c < cur.c)) if(clp.r < cur.r || (clp.r == cur.r && clp.c < cur.c))
start = clp, end = cur; start = clp, end = cur;
@ -128,30 +132,29 @@ void copy_selection() {
} }
} }
// Pasting // Pasting
void paste_selection(position p = cur) { void paste_selection(position p = cur + file_offset) {
if(selection.size() == 0) return; if(selection.size() == 0) return;
// Insert last line inside of this // Insert last line inside of this
insert(p, selection.find(selection.size()-1)->text); insert(p, selection.get(selection.size()-1));
if(selection.size() == 1) return; if(selection.size() == 1) return;
// Insert first line in front and split // Insert first line in front and split
split_line(p); split_line(p);
insert(p, selection.find(0)->text); insert(p, selection.get(0));
if(selection.size() == 2) return; if(selection.size() == 2) return;
// Insert lines // Insert lines
for(count_type i = selection.size()-2; i > 0; --i) for(count_type i = selection.size()-2; i > 0; --i)
new_line(p.r, selection.find(i)->text); new_line(p.r, selection.get(i));
} }
// TODO hledání a nahrazování
// TODO undo // TODO undo
// Jump to end of line // Jump to end of line
void jump_line_end() { void jump_line_end() {
count_type line_size = get_line(cur.r).size(); count_type line_size = get_line(file_offset+cur.r).size();
if(cur.c > line_size) if(cur.c > line_size)
cur.c = line_size; cur.c = line_size;
} }
@ -195,7 +198,7 @@ void move_cursor(char ch) {
break; break;
case 'l': case 'l':
if(cur.c < get_line(cur.r).size()) { if(cur.c < get_line(file_offset+cur.r).size()) {
cur.c += 1; cur.c += 1;
move(cur); move(cur);
} }
@ -246,26 +249,26 @@ int main(int argc, char* argv[]) {
char ch = getch(); char ch = getch();
switch(mode) { switch(mode) {
case NORMAL: case NORMAL:
print_line(cur.r); print_line(file_offset + cur.r);
switch(ch) { switch(ch) {
case 'h': case 'j': case 'k': case 'l': case 'h': case 'j': case 'k': case 'l':
move_cursor(ch); move_cursor(ch);
break; break;
case 'g': case 'g':
jump(get_number()); jump(get_number());
print_file(); print_file(file_offset);
break; break;
case 'd': case 'd':
remove(cur.r); remove(file_offset + cur.r);
print_file(cur.r); print_file(file_offset + cur.r);
break; break;
case 'x': case 'x':
remove(cur); remove(cur + file_offset);
print_line(cur.r); print_line(file_offset + cur.r);
break; break;
case 'o': case 'o':
new_line(cur.r); new_line(file_offset + cur.r);
print_file(cur.r); print_file(file_offset + cur.r);
break; break;
case 'q': case 'q':
run = false; run = false;
@ -278,11 +281,11 @@ int main(int argc, char* argv[]) {
break; break;
case 'v': case 'v':
mode = SELECT; mode = SELECT;
clp = cur; clp = cur + file_offset;
break; break;
case 'p': case 'p':
paste_selection(); paste_selection(cur + file_offset);
print_file(cur.r); print_file(file_offset + cur.r);
break; break;
default: default:
break; break;
@ -292,39 +295,39 @@ int main(int argc, char* argv[]) {
switch(ch) { switch(ch) {
case ESC: case ESC:
mode = NORMAL; mode = NORMAL;
print_line(cur.r); print_line(file_offset + cur.r);
break; break;
case BS: case BS:
if(cur.c > 0) { if(cur.c > 0) {
cur.c -= 1; cur.c -= 1;
remove(cur); remove(cur + file_offset);
} }
print_line(cur.r); print_line(file_offset + cur.r);
break; break;
case ENTER: case ENTER:
split_line(cur); split_line(cur + file_offset);
print_file(cur.r++); print_file(file_offset + cur.r++);
jump_line_end(); jump_line_end();
break; break;
default: default:
insert(cur, ch); insert(cur + file_offset, ch);
cur.c += 1; cur.c += 1;
print_line(cur.r); print_line(file_offset + cur.r);
break; break;
} }
break; break;
case SELECT: case SELECT:
print_line(cur.r); print_line(file_offset + cur.r);
switch(ch) { switch(ch) {
case 'h': case 'j': case 'k': case 'l': case 'h': case 'j': case 'k': case 'l':
move_cursor(ch); move_cursor(ch);
break; break;
case 'g': case 'g':
jump(get_number()); jump(get_number());
print_file(); print_file(file_offset);
break; break;
case 'v': case 'v':
copy_selection(); copy_selection(cur + file_offset);
mode = NORMAL; mode = NORMAL;
break; break;
default: default:

View file

@ -90,6 +90,9 @@ public:
// Don't find index k, but k-th line -> +1 // Don't find index k, but k-th line -> +1
return find(root, k+1); return find(root, k+1);
} }
string get(count_type k) {
return find(k)->text;
}
void clear() { void clear() {
while(size() > 0) { while(size() > 0) {
auto two = split(root, 1); auto two = split(root, 1);