summaryrefslogtreecommitdiff
path: root/config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'config.cpp')
-rw-r--r--config.cpp86
1 files changed, 74 insertions, 12 deletions
diff --git a/config.cpp b/config.cpp
index 76cf3a2..8bd86f7 100644
--- a/config.cpp
+++ b/config.cpp
@@ -1,25 +1,87 @@
+#include <cassert>
#include <termio.h>
#include "command.h"
#include "config.h"
+#include "throw.h"
using namespace std;
-Keybindings global_keybindings={
- {KEY_CTRL+'Q',{"quit_app"}},
- {KEY_BACKSPACE,{"delete_backward"}},
- {KEY_DELETE,{"delete_forward"}},
- {'\n',{"insert_newline"}},
- {'\t',{"insert_char","\t"}},
- {KEY_RIGHT,{"move_forward"}},
- {KEY_LEFT,{"move_backward"}},
- {KEY_DOWN,{"move_downward"}},
- {KEY_UP,{"move_upward"}},
-};
+KeyInputMachine global_keyinput({
+ {{KEY_CTRL+'X',KEY_CTRL+'Q'},{"quit_app"}},
+ {{KEY_BACKSPACE},{"delete_backward"}},
+ {{KEY_DELETE},{"delete_forward"}},
+ {{'\n'},{"insert_newline"}},
+ {{'\t'},{"insert_char","\t"}},
+ {{KEY_RIGHT},{"move_forward"}},
+ {{KEY_LEFT},{"move_backward"}},
+ {{KEY_DOWN},{"move_downward"}},
+ {{KEY_UP},{"move_upward"}},
+});
class Init{public: Init(){
for(int i=32;i<127;i++){
- global_keybindings.emplace(i,Command("insert_char",string(1,(char)i)));
+ global_keyinput.insert({i},Command("insert_char",string(1,(char)i)));
}
}} init_object;
+
+
+KeyInputMachine::TreeNode::~TreeNode(){
+ if(cmd)delete cmd;
+ if(m){
+ for(const pair<int,TreeNode*> &p : *m){
+ if(p.second!=nullptr)delete p.second;
+ }
+ }
+}
+
+KeyInputMachine::KeyInputMachine(){}
+
+KeyInputMachine::KeyInputMachine(const vector<pair<vector<int>,Command>> &list){
+ for(const pair<vector<int>,Command> &p : list){
+ insert(p.first,p.second);
+ }
+}
+
+void KeyInputMachine::insert(const vector<int> &keys,const Command &cmd){
+ assert(keys.size()>0);
+ TreeNode *node=&root;
+ for(int key : keys){
+ if(node->m==nullptr){
+ if(node->cmd){
+ THROW("Ambiguous keybinding!");
+ }
+ node->m=new unordered_map<int,TreeNode*>;
+ }
+ TreeNode *newnode=new TreeNode;
+ (*node->m)[key]=newnode;
+ node=newnode;
+ }
+ if(node->cmd!=nullptr)delete node->cmd;
+ node->cmd=new Command(cmd);
+}
+
+Either<bool,Command> KeyInputMachine::input(int key){
+ if(current->m==nullptr){
+ current=&root;
+ return {Left(),false};
+ }
+ auto it=current->m->find(key);
+ if(it==current->m->end()){
+ current=&root;
+ return {Left(),false};
+ }
+ current=it->second;
+ if(current->cmd!=nullptr){
+ Command *cmd=current->cmd;
+ current=&root;
+ return {Right(),*cmd};
+ } else {
+ return {Left(),true};
+ }
+}
+
+void KeyInputMachine::cancel(){
+ current=&root;
+}