#include #include #include "command.h" #include "config.h" #include "throw.h" using namespace std; KeyInputMachine global_keyinput({ {{KEY_CTRL+'Q',KEY_CTRL+'Q'},{"quit_app"}}, {{KEY_ALT+';'},{"display_prompt"}}, {{KEY_CTRL+'S'},{"save_file"}}, {{KEY_CTRL+'O'},{"open_prompt"}}, {{KEY_CTRL+'W'},{"close_tab"}}, {{KEY_ALT+'\t'},{"cycle_tabs"}}, {{KEY_ALT+KEY_SHIFTTAB},{"cycle_tabs_back"}}, {{KEY_ESC},{"cancel"}}, {{'\n'},{"insert_newline"}}, {{'\t'},{"insert_char","\t"}}, {{KEY_BACKSPACE},{"delete_backward"}}, {{KEY_DELETE},{"delete_forward"}}, {{KEY_RIGHT},{"move_forward"}}, {{KEY_LEFT},{"move_backward"}}, {{KEY_DOWN},{"move_downward"}}, {{KEY_UP},{"move_upward"}}, {{KEY_PAGEDOWN},{"move_pagedown"}}, {{KEY_PAGEUP},{"move_pageup"}}, }); class Init{public: Init(){ for(int i=32;i<127;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 &p : *m){ if(p.second!=nullptr)delete p.second; } } } KeyInputMachine::KeyInputMachine(){} KeyInputMachine::KeyInputMachine(const vector,Command>> &list){ for(const pair,Command> &p : list){ insert(p.first,p.second); } } void KeyInputMachine::insert(const vector &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; } TreeNode *newnode=new TreeNode; (*node->m)[key]=newnode; node=newnode; } if(node->cmd!=nullptr)delete node->cmd; node->cmd=new Command(cmd); } Either 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; }