#include #include #include "config.h" #include "manager.h" #include "throw.h" using namespace std; Manager::Manager() :activeIdx(-1){} void Manager::receive(const Command &cmd){ if(cmd[0]=="open_file"){ buffers.emplace_back(this); buffers.back().receive(cmd); activeIdx=buffers.size()-1; } else if(cmd[0]=="open_prompt"){ Maybe mfname=runPrompt("open: "); if(mfname.isNothing())return; buffers.emplace_back(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: "); if(mfname.isNothing())return; buffers[activeIdx].filename=mfname.fromJust(); buffers[activeIdx].receive({"save_file"}); } else if(cmd[0]=="error"||cmd[0]=="info"){ if(!have_screen)return; bool isError=cmd[0]=="error"; pushcursor(); Size termsize=gettermsize(); Style style={isError?1:9,9,isError,false}; fillrect(0,termsize.h-1,termsize.w,1,' '); moveto(0,termsize.h-1); setstyle(&style); tprintf("%s",cmd[1].data()); popcursor(); } else if(cmd[0]=="quit_app"){ should_quit=true; } else if(cmd[0]=="display_prompt"){ Maybe mline=runPrompt(":"); if(mline.isJust())receive({"info",{mline.fromJust()}}); } else { if(activeIdx==-1)bel(); else buffers[activeIdx].receive(cmd); } } void Manager::show(){ if(buffers.size()==0)return; string bartext; i64 hilight_start=-1,hilight_len; for(size_t i=0;i":buffers[i].filename; string tabtext=" "; for(size_t j=0;j=0;nameidx--){ if(fname[nameidx]=='/'){ nameidx++; break; } } //+1 because the first char was already appended tabtext+=fname.substr(nameidx+1,string::npos); tabtext+=' '; if((i64)i==activeIdx){ hilight_start=bartext.size(); hilight_len=tabtext.length(); } bartext+=tabtext; } assert(hilight_start!=-1); Size termsize=gettermsize(); i64 print_start=-1; if(bartext.size()<=(size_t)termsize.w){ print_start=0; } else { print_start=hilight_start+hilight_len/2-termsize.w/2; if(print_start<0){ print_start=0; } else if(print_start+(size_t)termsize.w>=bartext.size()){ print_start=bartext.size()-termsize.w; } } Style backStyle={7,0,false,false}; Style activeStyle={7,4,true,false}; pushcursor(); moveto(0,0); setstyle(&backStyle); fillrect(0,0,termsize.w,1,' '); if(print_start>=hilight_start+hilight_len||print_start+termsize.w<=hilight_start){ string text=bartext.substr(print_start,termsize.w); tprintf("%s",text.data()); } else { string text=bartext.substr(print_start,hilight_start-print_start); tprintf("%s",text.data()); text=bartext.substr(hilight_start,hilight_len); setstyle(&activeStyle); tprintf("%s",text.data()); text=bartext.substr(hilight_start+hilight_len,termsize.w-(hilight_start+hilight_len-print_start)); setstyle(&backStyle); tprintf("%s",text.data()); } popcursor(); } class TermioRAII{ bool *variable; public: TermioRAII(bool *variable):variable(variable){ initscreen(); initkeyboard(true); *variable=true; } ~TermioRAII(){ *variable=false; endkeyboard(); endscreen(); } }; int Manager::io(){ TermioRAII termioRAII(&have_screen); if(activeIdx==-1){ buffers.emplace_back(this); activeIdx=0; } while(true){ Size termsize=gettermsize(); show(); buffers[activeIdx].show(0,1,termsize.w,termsize.h-2); redraw(); int key=tgetkey(); Either ret=global_keyinput.input(key); if(ret.isLeft()){ if(!ret.fromLeft()){ bel(); receive({"error","Unbound key sequence"}); } } else { receive(ret.fromRight()); } if(should_quit)break; } return 0; } //Returns entered text, or Nothing if cancelled Maybe Manager::runPrompt(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()); } global_keyinput.cancel(); string inputLine; Buffer promptBuffer(this,true); while(true){ termsize=gettermsize(); promptBuffer.show(leftX,termsize.h-1,termsize.w-leftX,1); redraw(); int key=tgetkey(); Either ret=global_keyinput.input(key); if(ret.isLeft()){ if(!ret.fromLeft()){ bel(); } } else { Command cmd=ret.fromRight();; if(cmd[0]=="insert_newline"){ return promptBuffer.getText(); } else if(cmd[0]=="cancel"){ return {}; } else { promptBuffer.receive(cmd); } } } }