Generalize positions and count-type
This commit is contained in:
parent
76eac35213
commit
1e7ea2b5a2
1 changed files with 97 additions and 80 deletions
177
main.cpp
177
main.cpp
|
@ -13,32 +13,33 @@ using std::string;
|
|||
#define adds(s) addstr(s.c_str())
|
||||
enum mode_type { INSERT, NORMAL, SELECT };
|
||||
|
||||
struct position { count_type r, c; };
|
||||
|
||||
// Global variables
|
||||
treap file;
|
||||
int row = 0, col = 0;
|
||||
int file_offset = 0;
|
||||
int clp_r, clp_c;
|
||||
position cur = {0, 0};
|
||||
count_type file_offset = 0;
|
||||
position clp;
|
||||
treap selection;
|
||||
|
||||
// Accessing the file
|
||||
string get_line(int r) {
|
||||
string get_line(count_type r) {
|
||||
string line = (*file.find(file_offset+r)).text;
|
||||
for(int i = 0; i < line.size(); ++i)
|
||||
for(count_type i = 0; i < line.size(); ++i)
|
||||
if(line[i] == '\t')
|
||||
line[i] = ' ';
|
||||
return line;
|
||||
}
|
||||
char get(int r, int s) { return get_line(file_offset+r)[s]; }
|
||||
void set(int r, int s, char ch) { file.find(file_offset+r)->text[s] = ch; }
|
||||
void new_line(int r, string text = "") { file.insert(file_offset+r, text); }
|
||||
void insert(int r, int s, string t) { file.find(file_offset+r)->text.insert(s, t); }
|
||||
void insert(int r, int s, char ch) { insert(r, s, string{ch}); }
|
||||
char get(position p) { return get_line(file_offset+p.r)[p.c]; }
|
||||
void set(position p, char ch) { file.find(file_offset+p.r)->text[p.c] = ch; }
|
||||
void new_line(count_type r, string text = "") { file.insert(file_offset+r, text); }
|
||||
void insert(position p, string t) { file.find(file_offset+p.r)->text.insert(p.c, t); }
|
||||
void insert(position p, char ch) { insert(p, string{ch}); }
|
||||
void append(string t) { file.append(t); }
|
||||
void remove(int r, int s, int len=1) { file.find(file_offset+r)->text.erase(s,len); }
|
||||
void remove(int r) { file.remove(file_offset+r); }
|
||||
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); }
|
||||
|
||||
int get_number() {
|
||||
count_type get_number() {
|
||||
char ch = '0';
|
||||
string s = "";
|
||||
while(ch >= '0' && ch <= '9') {
|
||||
|
@ -65,82 +66,82 @@ bool save(string filename) {
|
|||
if(!outfile.good())
|
||||
return 1;
|
||||
|
||||
for(int i = 0; i < file.size(); ++i)
|
||||
for(count_type i = 0; i < file.size(); ++i)
|
||||
outfile << get_line(i-file_offset) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Clear line
|
||||
void clear_line(int pos) {
|
||||
move(pos, 0);
|
||||
void clear_line(count_type r) {
|
||||
move(r, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
// Print line
|
||||
void print_line(int pos) {
|
||||
clear_line(pos);
|
||||
move(pos, 0);
|
||||
adds(get_line(pos));
|
||||
void print_line(count_type r) {
|
||||
clear_line(r);
|
||||
move(r, 0);
|
||||
adds(get_line(r));
|
||||
}
|
||||
// Print file content
|
||||
void print_file(int start = 0) {
|
||||
for(int i = start; i < LINES; i++)
|
||||
void print_file(count_type start = 0) {
|
||||
for(count_type i = start; i < LINES; i++)
|
||||
if(file_offset+i < file.size())
|
||||
print_line(i);
|
||||
else
|
||||
clear_line(i);
|
||||
}
|
||||
// Splitting lines
|
||||
void split_line(int r, int s) {
|
||||
string line = get_line(r);
|
||||
string newline = line.substr(s, line.size());
|
||||
remove(r, s, line.size()-s);
|
||||
new_line(r+1, newline);
|
||||
void split_line(position p) {
|
||||
string line = get_line(p.r);
|
||||
string newline = line.substr(p.c, line.size());
|
||||
remove(p, line.size()-p.c);
|
||||
new_line(p.r+1, newline);
|
||||
}
|
||||
|
||||
// Copying
|
||||
void copy_selection() {
|
||||
// Determine first and last selected position
|
||||
int start_r = row, start_c = col, end_r = clp_r, end_c = clp_c;
|
||||
if(clp_r < row || (clp_r == row && clp_c < col))
|
||||
start_r = clp_r, start_c = clp_c, end_r = row, end_c = col;
|
||||
position start = cur, end = clp;
|
||||
if(clp.r < cur.r || (clp.r == cur.r && clp.c < cur.c))
|
||||
start = clp, end = cur;
|
||||
|
||||
// Clear previous selection
|
||||
selection.clear();
|
||||
|
||||
// Add all complete lines in between
|
||||
for(int r = start_r+1; r < end_r; ++r)
|
||||
for(count_type r = start.r+1; r < end.r; ++r)
|
||||
selection.append(get_line(r));
|
||||
|
||||
// Add first line end
|
||||
string start_line = get_line(start_r);
|
||||
int size = ((start_r == end_r) ? end_c+1 : start_line.size()) - start_c;
|
||||
string start = start_line.substr(start_c, size);
|
||||
selection.insert(0, start);
|
||||
string start_line = get_line(start.r);
|
||||
count_type size = ((start.r == end.r) ? end.c+1 : start_line.size()) - start.c;
|
||||
string start_text = start_line.substr(start.c, size);
|
||||
selection.insert(0, start_text);
|
||||
|
||||
// Add last line start
|
||||
if(start_r < end_r) {
|
||||
string end_line = get_line(end_r);
|
||||
string end = end_line.substr(0, end_c+1);
|
||||
selection.append(end);
|
||||
if(start.r < end.r) {
|
||||
string end_line = get_line(end.r);
|
||||
string end_text = end_line.substr(0, end.c+1);
|
||||
selection.append(end_text);
|
||||
}
|
||||
}
|
||||
// Pasting
|
||||
void paste_selection() {
|
||||
void paste_selection(position p = cur) {
|
||||
if(selection.size() == 0) return;
|
||||
|
||||
// Insert last line inside of this
|
||||
insert(row, col, selection.find(selection.size()-1)->text);
|
||||
insert(p, selection.find(selection.size()-1)->text);
|
||||
if(selection.size() == 1) return;
|
||||
|
||||
// Insert first line in front and split
|
||||
split_line(row, col);
|
||||
insert(row, col, selection.find(0)->text);
|
||||
split_line(p);
|
||||
insert(p, selection.find(0)->text);
|
||||
if(selection.size() == 2) return;
|
||||
|
||||
// Insert lines
|
||||
for(int i = selection.size()-2; i > 0; --i)
|
||||
new_line(row, selection.find(i)->text);
|
||||
for(count_type i = selection.size()-2; i > 0; --i)
|
||||
new_line(p.r, selection.find(i)->text);
|
||||
}
|
||||
|
||||
// TODO hledání a nahrazování
|
||||
|
@ -149,25 +150,30 @@ void paste_selection() {
|
|||
|
||||
// Jump to end of line
|
||||
void jump_line_end() {
|
||||
int line_size = get_line(row).size();
|
||||
if(col > line_size)
|
||||
col = line_size;
|
||||
count_type line_size = get_line(cur.r).size();
|
||||
if(cur.c > line_size)
|
||||
cur.c = line_size;
|
||||
}
|
||||
// Move cursor within window
|
||||
void move(position p) {
|
||||
move(p.r, p.c);
|
||||
}
|
||||
// Cursor movement
|
||||
void move_cursor(char ch) {
|
||||
switch(ch) {
|
||||
case 'h':
|
||||
if(col > 0)
|
||||
move(row, --col);
|
||||
if(cur.c > 0)
|
||||
move(cur.r, --cur.c);
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
if(file_offset + row >= file.size()-1) break;
|
||||
if(row < LINES-1) {
|
||||
move(++row, col);
|
||||
if(file_offset + cur.r >= file.size()-1) break;
|
||||
if(cur.r < LINES-1) {
|
||||
cur.r += 1;
|
||||
move(cur);
|
||||
jump_line_end();
|
||||
}
|
||||
else if(row == LINES-1) {
|
||||
else if(cur.r == LINES-1) {
|
||||
file_offset++;
|
||||
jump_line_end();
|
||||
print_file();
|
||||
|
@ -175,8 +181,9 @@ void move_cursor(char ch) {
|
|||
break;
|
||||
|
||||
case 'k':
|
||||
if(row > 0) {
|
||||
move(--row, col);
|
||||
if(cur.r > 0) {
|
||||
cur.r -= 1;
|
||||
move(cur);
|
||||
jump_line_end();
|
||||
}
|
||||
else if(file_offset > 0) {
|
||||
|
@ -187,15 +194,22 @@ void move_cursor(char ch) {
|
|||
break;
|
||||
|
||||
case 'l':
|
||||
if(col < get_line(row).size())
|
||||
move(row, ++col);
|
||||
if(cur.c < get_line(cur.r).size()) {
|
||||
cur.c += 1;
|
||||
move(cur);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Skoky a přesuny
|
||||
void jump(int r) {
|
||||
file_offset = std::min(r, std::max((int)(file.size()-LINES), 0));
|
||||
row = 0;
|
||||
void jump(count_type r) {
|
||||
count_type last_start = file.size()-LINES;
|
||||
if(last_start < 0)
|
||||
last_start = 0;
|
||||
file_offset = r;
|
||||
if(file_offset > last_start)
|
||||
file_offset = last_start;
|
||||
cur.r = 0;
|
||||
jump_line_end();
|
||||
}
|
||||
|
||||
|
@ -219,11 +233,11 @@ int main(int argc, char* argv[]) {
|
|||
// Main loop
|
||||
bool run = true;
|
||||
while(run) {
|
||||
move(row, col);
|
||||
move(cur);
|
||||
char ch = getch();
|
||||
switch(mode) {
|
||||
case NORMAL:
|
||||
print_line(row);
|
||||
print_line(cur.r);
|
||||
switch(ch) {
|
||||
case 'h': case 'j': case 'k': case 'l':
|
||||
move_cursor(ch);
|
||||
|
@ -233,16 +247,16 @@ int main(int argc, char* argv[]) {
|
|||
print_file();
|
||||
break;
|
||||
case 'd':
|
||||
remove(row);
|
||||
print_file(row);
|
||||
remove(cur.r);
|
||||
print_file(cur.r);
|
||||
break;
|
||||
case 'x':
|
||||
remove(row, col);
|
||||
print_line(row);
|
||||
remove(cur);
|
||||
print_line(cur.r);
|
||||
break;
|
||||
case 'o':
|
||||
new_line(row);
|
||||
print_file(row);
|
||||
new_line(cur.r);
|
||||
print_file(cur.r);
|
||||
break;
|
||||
case 'q':
|
||||
run = false;
|
||||
|
@ -255,11 +269,11 @@ int main(int argc, char* argv[]) {
|
|||
break;
|
||||
case 'v':
|
||||
mode = SELECT;
|
||||
clp_r = row, clp_c = col;
|
||||
clp = cur;
|
||||
break;
|
||||
case 'p':
|
||||
paste_selection();
|
||||
print_file(row);
|
||||
print_file(cur.r);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -269,26 +283,29 @@ int main(int argc, char* argv[]) {
|
|||
switch(ch) {
|
||||
case ESC:
|
||||
mode = NORMAL;
|
||||
print_line(row);
|
||||
print_line(cur.r);
|
||||
break;
|
||||
case BS:
|
||||
if(col>0)
|
||||
remove(row, --col);
|
||||
print_line(row);
|
||||
if(cur.c > 0) {
|
||||
cur.c -= 1;
|
||||
remove(cur);
|
||||
}
|
||||
print_line(cur.r);
|
||||
break;
|
||||
case ENTER:
|
||||
split_line(row, col);
|
||||
print_file(row++);
|
||||
split_line(cur);
|
||||
print_file(cur.r++);
|
||||
jump_line_end();
|
||||
break;
|
||||
default:
|
||||
insert(row, col++, ch);
|
||||
print_line(row);
|
||||
insert(cur, ch);
|
||||
cur.c += 1;
|
||||
print_line(cur.r);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SELECT:
|
||||
print_line(row);
|
||||
print_line(cur.r);
|
||||
switch(ch) {
|
||||
case 'h': case 'j': case 'k': case 'l':
|
||||
move_cursor(ch);
|
||||
|
|
Loading…
Reference in a new issue