Unite everything with file_offset
This commit is contained in:
parent
a9bc74264d
commit
fe62172682
2 changed files with 50 additions and 44 deletions
91
main.cpp
91
main.cpp
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue