From 66e0b88d27966adae568f4f2ddbf2ff10bb812d9 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Thu, 12 Jan 2017 22:10:20 +0100 Subject: Proper tab closing --- buffer.cpp | 4 ++- config.cpp | 1 + manager.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++++------------ manager.h | 6 ++-- 4 files changed, 98 insertions(+), 25 deletions(-) diff --git a/buffer.cpp b/buffer.cpp index b185b99..6fa7420 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -189,6 +189,8 @@ void Buffer::handleCommand(const Command &cmd){ } else { cursor.x=screen[sp.y].cells[sp.x].linex; } + } else if(cmd[0]=="cancel"){ + bel(); //nothing to cancel, apparently } else { THROW("Unknown command: "+cmd[0]); } @@ -401,7 +403,7 @@ Buffer::Screenpos Buffer::findCursorInScreen() const { } } -i64 numberWidth(i64 number){ +static i64 numberWidth(i64 number){ if(number<0)return 1+numberWidth(-number); if(number==0)return 1; return (i64)log10(number)+1; diff --git a/config.cpp b/config.cpp index f5b5987..77e3ed5 100644 --- a/config.cpp +++ b/config.cpp @@ -13,6 +13,7 @@ KeyInputMachine global_keyinput({ {{KEY_ALT+';'},{"display_prompt"}}, {{KEY_CTRL+'S'},{"save_file"}}, {{KEY_CTRL+'O'},{"open_prompt"}}, + {{KEY_CTRL+'W'},{"close_tab"}}, {{KEY_ESC},{"cancel"}}, diff --git a/manager.cpp b/manager.cpp index a3e9738..fdc7641 100644 --- a/manager.cpp +++ b/manager.cpp @@ -11,26 +11,45 @@ using namespace std; Manager::Manager() :activeIdx(-1){} +Manager::~Manager(){ + for(Buffer *buffer : buffers){ + delete buffer; + } +} + void Manager::receive(const Command &cmd){ if(cmd[0]=="open_file"){ - buffers.emplace_back(this); - buffers.back().receive(cmd); + buffers.push_back(new Buffer(this)); + buffers.back()->receive(cmd); activeIdx=buffers.size()-1; } else if(cmd[0]=="open_prompt"){ - Maybe mfname=runPrompt("open: "); + Maybe mfname=promptString("open: "); if(mfname.isNothing())return; - buffers.emplace_back(this); - buffers.back().receive({"open_file",mfname.fromJust()}); + buffers.push_back(new Buffer(this)); + buffers.back()->receive({"open_file",mfname.fromJust()}); activeIdx=buffers.size()-1; } else if(cmd[0]=="save_prompt"){ if(activeIdx==-1){ receive({"error","No buffers open!"}); return; } - Maybe mfname=runPrompt("save: "); + Maybe mfname=promptString("save: "); if(mfname.isNothing())return; - buffers[activeIdx].filename=mfname.fromJust(); - buffers[activeIdx].receive({"save_file"}); + buffers[activeIdx]->filename=mfname.fromJust(); + buffers[activeIdx]->receive({"save_file"}); + } else if(cmd[0]=="close_tab"){ + if(activeIdx==-1){ + receive({"error","No buffers open!"}); + return; + } + if(buffers[activeIdx]->isDirty()){ + char choice=promptChar("Unsaved changes; discard? [y/N]","yn",'n'); + if(choice=='n')return; + } + delete buffers[activeIdx]; + buffers.erase(buffers.begin()+activeIdx); + if(activeIdx>0)activeIdx--; + if(buffers.size()==0)buffers.push_back(new Buffer(this)); } else if(cmd[0]=="error"||cmd[0]=="info"){ if(!have_screen)return; bool isError=cmd[0]=="error"; @@ -43,13 +62,23 @@ void Manager::receive(const Command &cmd){ tprintf("%s",cmd[1].data()); popcursor(); } else if(cmd[0]=="quit_app"){ + Size termsize=gettermsize(); + for(i64 i=0;i<(i64)buffers.size();i++){ + if(!buffers[i]->isDirty())continue; + activeIdx=i; + buffers[activeIdx]->show(0,1,termsize.w,termsize.h-2); + show(); + if(promptChar("Unsaved changes in this buffer; discard? [y/N]","yn",'n')=='n'){ + return; + } + } should_quit=true; } else if(cmd[0]=="display_prompt"){ - Maybe mline=runPrompt(":"); + Maybe mline=promptString(":"); if(mline.isJust())receive({"info",{mline.fromJust()}}); } else { if(activeIdx==-1)bel(); - else buffers[activeIdx].receive(cmd); + else buffers[activeIdx]->receive(cmd); } } @@ -59,7 +88,7 @@ void Manager::show(){ string bartext; i64 hilight_start=-1,hilight_len; for(size_t i=0;i":buffers[i].filename; + string fname=buffers[i]->filename.size()==0?"":buffers[i]->filename; string tabtext=" "; for(size_t j=0;jisDirty())tabtext+='*'; tabtext+=' '; if((i64)i==activeIdx){ @@ -152,14 +181,14 @@ int Manager::io(){ TermioRAII termioRAII(&have_screen); if(activeIdx==-1){ - buffers.emplace_back(this); + buffers.push_back(new Buffer(this)); activeIdx=0; } while(true){ Size termsize=gettermsize(); show(); - buffers[activeIdx].show(0,1,termsize.w,termsize.h-2); + buffers[activeIdx]->show(0,1,termsize.w,termsize.h-2); redraw(); int key=tgetkey(); @@ -180,17 +209,24 @@ int Manager::io(){ } +string truncatePromptString(const string &promptString,i64 width){ + if((i64)promptString.size()>width*3/4){ + string truncated(promptString.begin(),promptString.begin()+(width*3/4-3)); + return truncated+"..."; + } else { + return promptString; + } +} + //Returns entered text, or Nothing if cancelled -Maybe Manager::runPrompt(const string &promptString){ +Maybe Manager::promptString(const string &promptString){ Size termsize=gettermsize(); moveto(0,termsize.h-1); - i64 leftX=promptString.size(); - if((i64)promptString.size()>termsize.w*3/4){ - string truncated(promptString.begin(),promptString.begin()+(termsize.w*3/4-3)); - tprintf("%s...",truncated.data()); - } else { - tprintf("%s",promptString.data()); - } + string truncated=truncatePromptString(promptString,termsize.w); + i64 leftX=truncated.size(); + Style promptStyle={9,9,false,false}; + setstyle(&promptStyle); + tprintf("%s",truncated.data()); global_keyinput.cancel(); @@ -211,8 +247,12 @@ Maybe Manager::runPrompt(const string &promptString){ } else { Command cmd=ret.fromRight();; if(cmd[0]=="insert_newline"){ + termsize=gettermsize(); + fillrect(0,termsize.h-1,termsize.w,1,' '); return promptBuffer.getText(); } else if(cmd[0]=="cancel"){ + termsize=gettermsize(); + fillrect(0,termsize.h-1,termsize.w,1,' '); return {}; } else { promptBuffer.receive(cmd); @@ -220,3 +260,31 @@ Maybe Manager::runPrompt(const string &promptString){ } } } + +char Manager::promptChar(const string &promptString,const string &options,char def){ + Size termsize=gettermsize(); + moveto(0,termsize.h-1); + string truncated=truncatePromptString(promptString,termsize.w); + Style promptStyle={9,9,false,false}; + setstyle(&promptStyle); + tprintf("%s",truncated.data()); + redraw(); + + global_keyinput.cancel(); + + while(true){ + int key=tgetkey(); + if(key==KEY_ESC)return def; + if(key<=0||key>=127){ + bel(); + continue; + } + key=tolower(key); + if(options.find((char)key)!=string::npos){ + termsize=gettermsize(); + fillrect(0,termsize.h-1,termsize.w,1,' '); + return (char)key; + } + bel(); + } +} diff --git a/manager.h b/manager.h index 55dfc96..80f9ef9 100644 --- a/manager.h +++ b/manager.h @@ -11,16 +11,18 @@ using namespace std; class Manager{ - vector buffers; + vector buffers; i64 activeIdx; bool should_quit=false; bool have_screen=false; - Maybe runPrompt(const string &promptString); + Maybe promptString(const string &promptString); + char promptChar(const string &promptString,const string &options,char def); public: Manager(); + ~Manager(); void receive(const Command &cmd); void show(); -- cgit v1.2.3-54-g00ecf