summaryrefslogtreecommitdiff
path: root/manager.cpp
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-01-08 22:43:35 +0100
committertomsmeding <tom.smeding@gmail.com>2017-01-08 22:43:35 +0100
commit4addb711c6a1a282b0a59bf03e850a86ba2ead69 (patch)
treef7e9c4a594d1c4fa41a6ebc6371279762a9a580a /manager.cpp
Initial
Diffstat (limited to 'manager.cpp')
-rw-r--r--manager.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/manager.cpp b/manager.cpp
new file mode 100644
index 0000000..01c9e01
--- /dev/null
+++ b/manager.cpp
@@ -0,0 +1,151 @@
+#include <cassert>
+#include <termio.h>
+
+#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);
+ } else if(cmd[0]=="insert_char"){
+ if(activeIdx==-1)bel();
+ else buffers[activeIdx].receive(cmd);
+ } else if(cmd[0]=="error"){
+ pushcursor();
+ Size termsize=gettermsize();
+ moveto(0,termsize.h-1);
+ Style errorStyle={1,9,true,false};
+ setstyle(&errorStyle);
+ tprintf("%s",cmd[1].data());
+ popcursor();
+ } else if(cmd[0]=="quit_app"){
+ should_quit=true;
+ } else {
+ THROW("Unknown command");
+ }
+}
+
+void Manager::show(){
+ if(buffers.size()==0)return;
+
+ string bartext;
+ i64 hilight_start=-1,hilight_len;
+ for(size_t i=0;i<buffers.size();i++){
+ const string &fname=buffers[i].filename.size()==0?"<New file>":buffers[i].filename;
+ string tabtext=" ";
+ for(size_t j=0;j<fname.size();j++){
+ if(fname[j]=='/'){
+ tabtext+='/';
+ if(j+1<fname.size()){
+ tabtext+=fname[j+1];
+ j++;
+ }
+ }
+ }
+
+ i64 nameidx;
+ for(nameidx=fname.size()-1;nameidx>=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);
+ 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{
+public:
+ TermioRAII(){
+ initscreen();
+ initkeyboard(true);
+ }
+ ~TermioRAII(){
+ endkeyboard();
+ endscreen();
+ }
+};
+
+int Manager::io(){
+ TermioRAII termioRAII;
+
+ 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();
+
+ auto it=global_keybindings.find(key);
+ if(it!=global_keybindings.end()){
+ receive(it->second);
+ } else {
+ receive({"error","Unbound key: "+to_string(key)});
+ }
+ if(should_quit)break;
+ }
+
+ return 0;
+}