From 3e434c89de052c1909952746368e837fb68e0ae2 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Tue, 10 Jan 2017 10:13:17 +0100 Subject: Move downward --- buffer.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++------------------ buffer.h | 9 +++++ 2 files changed, 101 insertions(+), 37 deletions(-) diff --git a/buffer.cpp b/buffer.cpp index 78f5e16..9b91e43 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -1,5 +1,6 @@ -#include +#include #include +#include #include #include #include @@ -15,8 +16,8 @@ using namespace std; Buffer::Buffer(Manager *manager) :manager(manager){} -void Buffer::receive(const Command &cmd){ - //TODO: optimise the renewLayout's in this function +void Buffer::handleCommand(const Command &cmd){ + //TODO: optimise the relayoutScreen's in this function if(cmd[0]=="open_file"){ const string &fname=cmd[1]; @@ -29,67 +30,100 @@ void Buffer::receive(const Command &cmd){ tb.read(file); } else if(cmd[0]=="insert_char"){ char c=cmd[1][0]; - if(c=='\n'){ - assert(false); - } else { - tb.insert(cursor.line,cursor.x,cmd[1][0]); - cursor.x++; - } - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + assert(c!='\n'); + tb.insert(cursor.line,cursor.x,cmd[1][0]); + cursor.x++; + relayoutScreen(); } else if(cmd[0]=="insert_newline"){ tb.insert(cursor.line,cursor.x,'\n'); cursor.x=0; cursor.line++; - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + relayoutScreen(); } else if(cmd[0]=="delete_backward"){ if(cursor.x==0&&cursor.line==0){ bel(); + return; + } + if(cursor.x>0){ + cursor.x--; + tb.erase(cursor.line,cursor.x); } else { - if(cursor.x>0){ - cursor.x--; - tb.erase(cursor.line,cursor.x); - } else { - cursor.line--; - cursor.x=tb.lineLen(cursor.line); - tb.erase(cursor.line,cursor.x); - } - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + cursor.line--; + cursor.x=tb.lineLen(cursor.line); + tb.erase(cursor.line,cursor.x); } + relayoutScreen(); } else if(cmd[0]=="delete_forward"){ if(cursor.line==tb.numLines()-1&&cursor.x==tb.lineLen(cursor.line)){ bel(); - } else { - tb.erase(cursor.line,cursor.x); - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + return; } + tb.erase(cursor.line,cursor.x); + relayoutScreen(); } else if(cmd[0]=="move_forward"){ if(cursor.line==tb.numLines()-1&&cursor.x==tb.lineLen(cursor.line)){ bel(); + return; + } + if(cursor.x==tb.lineLen(cursor.line)){ + cursor.x=0; + cursor.line++; } else { - if(cursor.x==tb.lineLen(cursor.line)){ - cursor.x=0; - cursor.line++; - } else { - cursor.x++; - } - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + cursor.x++; } } else if(cmd[0]=="move_backward"){ if(cursor.line==0&&cursor.x==0){ bel(); + return; + } + if(cursor.x==0){ + cursor.line--; + cursor.x=tb.lineLen(cursor.line); } else { - if(cursor.x==0){ - cursor.line--; - cursor.x=tb.lineLen(cursor.line); - } else { - cursor.x--; + cursor.x--; + } + } else if(cmd[0]=="move_downward"){ + Screenpos sp=findCursorInScreen(); + if(sp.x==-1){ + bel(); + return; + } + if(sp.y==(i64)screen.size()-1){ + if(screen[sp.y].line==tb.numLines()-1&& + (screen[sp.y].cells.size()==0 + ?tb.lineLen(screen[sp.y].line)==0 + :screen[sp.y].cells.back().linex==tb.lineLen(screen[sp.y].line)-1)){ + //so screen[sp.y] contains the end of that logical line + if(cursor.x==tb.lineLen(screen[sp.y].line)){ + bel(); + } else { + cursor.x=tb.lineLen(screen[sp.y].line); + } + return; } - renewLayout(screen[0].line,screen[0].part,lastWidth,lastHeight); + screen.erase(screen.begin()); + relayoutScreen(); + } else { + sp.y++; + } + if(sp.y>=(i64)screen.size()){ + bel(); + return; + } + cursor.line=screen[sp.y].line; + if(sp.x>=(i64)screen[sp.y].cells.size()){ + cursor.x=tb.lineLen(cursor.line); + } else { + cursor.x=screen[sp.y].cells[sp.x].linex; } } else { THROW("Unknown command"); } - //cerr<<"New cursor is (line="< &cells=lineit->cells; + auto chrit=lower_bound(cells.begin(),cells.end(),cursor.x,[](const Cell &cell,i64 x){ + return cell.linex layoutLine(const string &line,i64 linenum,i64 width); void performInitialLayout(i64 width,i64 height); void renewLayout(i64 topLine,i64 topPart,i64 width,i64 height); + void relayoutScreen(); + + Screenpos findCursorInScreen() const; + + void handleCommand(const Command &cmd); public: string filename; -- cgit v1.2.3-70-g09d2