Use a HashMap to store the normal mode keymap

This commit is contained in:
Maxime Coste 2017-03-16 23:40:38 +00:00
parent e44f95820e
commit 8b1078e510
4 changed files with 151 additions and 162 deletions

View File

@ -258,21 +258,19 @@ public:
context().client().info_hide(); context().client().info_hide();
do_restore_hooks = true; do_restore_hooks = true;
auto it = std::lower_bound(keymap.begin(), keymap.end(), key, auto it = keymap.find(key);
[](const NormalCmdDesc& lhs, const Key& rhs)
{ return lhs.key < rhs; });
if (it != keymap.end() and it->key == key) if (it != keymap.end() and it->key == key)
{ {
auto autoinfo = context().options()["autoinfo"].get<AutoInfo>(); auto autoinfo = context().options()["autoinfo"].get<AutoInfo>();
if (autoinfo & AutoInfo::Normal and context().has_client()) if (autoinfo & AutoInfo::Normal and context().has_client())
context().client().info_show(key_to_str(key), it->docstring.str(), context().client().info_show(key_to_str(key), it->value.docstring.str(),
{}, InfoStyle::Prompt); {}, InfoStyle::Prompt);
// reset m_params now to be reentrant // reset m_params now to be reentrant
NormalParams params = m_params; NormalParams params = m_params;
m_params = { 0, 0 }; m_params = { 0, 0 };
it->func(context(), params); it->value.func(context(), params);
} }
} }

View File

@ -805,10 +805,6 @@ int main(int argc, char* argv[])
}; };
try try
{ {
std::sort(keymap.begin(), keymap.end(),
[](const NormalCmdDesc& lhs, const NormalCmdDesc& rhs)
{ return lhs.key < rhs.key; });
ParametersParser parser(params, param_desc); ParametersParser parser(params, param_desc);
const bool list_sessions = (bool)parser.get_switch("l"); const bool list_sessions = (bool)parser.get_switch("l");

View File

@ -1779,190 +1779,187 @@ void force_redraw(Context& context, NormalParams)
} }
} }
static NormalCmdDesc cmds[] = const HashMap<Key, NormalCmd> keymap{
{ { {'h'}, {"move left", move<CharCount, Backward>} },
{ 'h', "move left", move<CharCount, Backward> }, { {'j'}, {"move down", move<LineCount, Forward>} },
{ 'j', "move down", move<LineCount, Forward> }, { {'k'}, {"move up", move<LineCount, Backward>} },
{ 'k', "move up", move<LineCount, Backward> }, { {'l'}, {"move right", move<CharCount, Forward>} },
{ 'l', "move right", move<CharCount, Forward> },
{ 'H', "extend left", move<CharCount, Backward, SelectMode::Extend> }, { {'H'}, {"extend left", move<CharCount, Backward, SelectMode::Extend>} },
{ 'J', "extend down", move<LineCount, Forward, SelectMode::Extend> }, { {'J'}, {"extend down", move<LineCount, Forward, SelectMode::Extend>} },
{ 'K', "extend up", move<LineCount, Backward, SelectMode::Extend> }, { {'K'}, {"extend up", move<LineCount, Backward, SelectMode::Extend>} },
{ 'L', "extend right", move<CharCount, Forward, SelectMode::Extend> }, { {'L'}, {"extend right", move<CharCount, Forward, SelectMode::Extend>} },
{ 't', "select to next character", select_to_next_char<SelectFlags::None> }, { {'t'}, {"select to next character", select_to_next_char<SelectFlags::None>} },
{ 'f', "select to next character included", select_to_next_char<SelectFlags::Inclusive> }, { {'f'}, {"select to next character included", select_to_next_char<SelectFlags::Inclusive>} },
{ 'T', "extend to next character", select_to_next_char<SelectFlags::Extend> }, { {'T'}, {"extend to next character", select_to_next_char<SelectFlags::Extend>} },
{ 'F', "extend to next character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend> }, { {'F'}, {"extend to next character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend>} },
{ alt('t'), "select to previous character", select_to_next_char<SelectFlags::Reverse> }, { {alt('t')}, {"select to previous character", select_to_next_char<SelectFlags::Reverse>} },
{ alt('f'), "select to previous character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Reverse> }, { {alt('f')}, {"select to previous character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Reverse>} },
{ alt('T'), "extend to previous character", select_to_next_char<SelectFlags::Extend | SelectFlags::Reverse> }, { {alt('T')}, {"extend to previous character", select_to_next_char<SelectFlags::Extend | SelectFlags::Reverse>} },
{ alt('F'), "extend to previous character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend | SelectFlags::Reverse> }, { {alt('F')}, {"extend to previous character included", select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend | SelectFlags::Reverse>} },
{ 'd', "erase selected text", erase_selections }, { {'d'}, {"erase selected text", erase_selections} },
{ 'c', "change selected text", change }, { {'c'}, {"change selected text", change} },
{ 'i', "insert before selected text", enter_insert_mode<InsertMode::Insert> }, { {'i'}, {"insert before selected text", enter_insert_mode<InsertMode::Insert>} },
{ 'I', "insert at line begin", enter_insert_mode<InsertMode::InsertAtLineBegin> }, { {'I'}, {"insert at line begin", enter_insert_mode<InsertMode::InsertAtLineBegin>} },
{ 'a', "insert after selected text", enter_insert_mode<InsertMode::Append> }, { {'a'}, {"insert after selected text", enter_insert_mode<InsertMode::Append>} },
{ 'A', "insert at line end", enter_insert_mode<InsertMode::AppendAtLineEnd> }, { {'A'}, {"insert at line end", enter_insert_mode<InsertMode::AppendAtLineEnd>} },
{ 'o', "insert on new line below", enter_insert_mode<InsertMode::OpenLineBelow> }, { {'o'}, {"insert on new line below", enter_insert_mode<InsertMode::OpenLineBelow>} },
{ 'O', "insert on new line above", enter_insert_mode<InsertMode::OpenLineAbove> }, { {'O'}, {"insert on new line above", enter_insert_mode<InsertMode::OpenLineAbove>} },
{ 'r', "replace with character", replace_with_char }, { {'r'}, {"replace with character", replace_with_char} },
{ 'g', "go to location", goto_commands<SelectMode::Replace> }, { {'g'}, {"go to location", goto_commands<SelectMode::Replace>} },
{ 'G', "extend to location", goto_commands<SelectMode::Extend> }, { {'G'}, {"extend to location", goto_commands<SelectMode::Extend>} },
{ 'v', "move view", view_commands<false> }, { {'v'}, {"move view", view_commands<false>} },
{ 'V', "move view (locked)", view_commands<true> }, { {'V'}, {"move view (locked)", view_commands<true>} },
{ 'y', "yank selected text", yank }, { {'y'}, {"yank selected text", yank} },
{ 'p', "paste after selected text", repeated<paste<InsertMode::Append>> }, { {'p'}, {"paste after selected text", repeated<paste<InsertMode::Append>>} },
{ 'P', "paste before selected text", repeated<paste<InsertMode::Insert>> }, { {'P'}, {"paste before selected text", repeated<paste<InsertMode::Insert>>} },
{ alt('p'), "paste every yanked selection after selected text", paste_all<InsertMode::Append> }, { {alt('p')}, {"paste every yanked selection after selected text", paste_all<InsertMode::Append>} },
{ alt('P'), "paste every yanked selection before selected text", paste_all<InsertMode::Insert> }, { {alt('P')}, {"paste every yanked selection before selected text", paste_all<InsertMode::Insert>} },
{ 'R', "replace selected text with yanked text", paste<InsertMode::Replace> }, { {'R'}, {"replace selected text with yanked text", paste<InsertMode::Replace>} },
{ alt('R'), "replace selected text with yanked text", paste_all<InsertMode::Replace> }, { {alt('R')}, {"replace selected text with yanked text", paste_all<InsertMode::Replace>} },
{ 's', "select regex matches in selected text", select_regex }, { {'s'}, {"select regex matches in selected text", select_regex} },
{ 'S', "split selected text on regex matches", split_regex }, { {'S'}, {"split selected text on regex matches", split_regex} },
{ alt('s'), "split selected text on line ends", split_lines }, { {alt('s')}, {"split selected text on line ends", split_lines} },
{ '.', "repeat last insert command", repeat_last_insert }, { {'.'}, {"repeat last insert command", repeat_last_insert} },
{ alt('.'), "repeat last object select/character find", repeat_last_select }, { {alt('.')}, {"repeat last object select/character find", repeat_last_select} },
{ '%', "select whole buffer", select_whole_buffer }, { {'%'}, {"select whole buffer", select_whole_buffer} },
{ ':', "enter command prompt", command }, { {':'}, {"enter command prompt", command} },
{ '|', "pipe each selection through filter and replace with output", pipe<true> }, { {'|'}, {"pipe each selection through filter and replace with output", pipe<true>} },
{ alt('|'), "pipe each selection through command and ignore output", pipe<false> }, { {alt('|')}, {"pipe each selection through command and ignore output", pipe<false>} },
{ '!', "insert command output", insert_output<InsertMode::Insert> }, { {'!'}, {"insert command output", insert_output<InsertMode::Insert>} },
{ alt('!'), "append command output", insert_output<InsertMode::Append> }, { {alt('!')}, {"append command output", insert_output<InsertMode::Append>} },
{ ' ', "remove all selection except main", keep_selection }, { {' '}, {"remove all selection except main", keep_selection} },
{ alt(' '), "remove main selection", remove_selection }, { {alt(' ')}, {"remove main selection", remove_selection} },
{ ';', "reduce selections to their cursor", clear_selections }, { {';'}, {"reduce selections to their cursor", clear_selections} },
{ alt(';'), "swap selections cursor and anchor", flip_selections }, { {alt(';')}, {"swap selections cursor and anchor", flip_selections} },
{ alt(':'), "ensure selection cursor is after anchor", ensure_forward }, { {alt(':')}, {"ensure selection cursor is after anchor", ensure_forward} },
{ alt('m'), "merge consecutive selections", merge_consecutive }, { {alt('m')}, {"merge consecutive selections", merge_consecutive} },
{ 'w', "select to next word start", repeated<&select<SelectMode::Replace, select_to_next_word<Word>>> }, { {'w'}, {"select to next word start", repeated<&select<SelectMode::Replace, select_to_next_word<Word>>>} },
{ 'e', "select to next word end", repeated<select<SelectMode::Replace, select_to_next_word_end<Word>>> }, { {'e'}, {"select to next word end", repeated<select<SelectMode::Replace, select_to_next_word_end<Word>>>} },
{ 'b', "select to previous word start", repeated<select<SelectMode::Replace, select_to_previous_word<Word>>> }, { {'b'}, {"select to previous word start", repeated<select<SelectMode::Replace, select_to_previous_word<Word>>>} },
{ 'W', "extend to next word start", repeated<select<SelectMode::Extend, select_to_next_word<Word>>> }, { {'W'}, {"extend to next word start", repeated<select<SelectMode::Extend, select_to_next_word<Word>>>} },
{ 'E', "extend to next word end", repeated<select<SelectMode::Extend, select_to_next_word_end<Word>>> }, { {'E'}, {"extend to next word end", repeated<select<SelectMode::Extend, select_to_next_word_end<Word>>>} },
{ 'B', "extend to previous word start", repeated<select<SelectMode::Extend, select_to_previous_word<Word>>> }, { {'B'}, {"extend to previous word start", repeated<select<SelectMode::Extend, select_to_previous_word<Word>>>} },
{ alt('w'), "select to next WORD start", repeated<select<SelectMode::Replace, select_to_next_word<WORD>>> }, { {alt('w')}, {"select to next WORD start", repeated<select<SelectMode::Replace, select_to_next_word<WORD>>>} },
{ alt('e'), "select to next WORD end", repeated<select<SelectMode::Replace, select_to_next_word_end<WORD>>> }, { {alt('e')}, {"select to next WORD end", repeated<select<SelectMode::Replace, select_to_next_word_end<WORD>>>} },
{ alt('b'), "select to previous WORD start", repeated<select<SelectMode::Replace, select_to_previous_word<WORD>>> }, { {alt('b')}, {"select to previous WORD start", repeated<select<SelectMode::Replace, select_to_previous_word<WORD>>>} },
{ alt('W'), "extend to next WORD start", repeated<select<SelectMode::Extend, select_to_next_word<WORD>>> }, { {alt('W')}, {"extend to next WORD start", repeated<select<SelectMode::Extend, select_to_next_word<WORD>>>} },
{ alt('E'), "extend to next WORD end", repeated<select<SelectMode::Extend, select_to_next_word_end<WORD>>> }, { {alt('E')}, {"extend to next WORD end", repeated<select<SelectMode::Extend, select_to_next_word_end<WORD>>>} },
{ alt('B'), "extend to previous WORD start", repeated<select<SelectMode::Extend, select_to_previous_word<WORD>>> }, { {alt('B')}, {"extend to previous WORD start", repeated<select<SelectMode::Extend, select_to_previous_word<WORD>>>} },
{ alt('l'), "select to line end", repeated<select<SelectMode::Replace, select_to_line_end<false>>> }, { {alt('l')}, {"select to line end", repeated<select<SelectMode::Replace, select_to_line_end<false>>>} },
{ Key::End, "select to line end", repeated<select<SelectMode::Replace, select_to_line_end<false>>> }, { {Key::End}, {"select to line end", repeated<select<SelectMode::Replace, select_to_line_end<false>>>} },
{ alt('L'), "extend to line end", repeated<select<SelectMode::Extend, select_to_line_end<false>>> }, { {alt('L')}, {"extend to line end", repeated<select<SelectMode::Extend, select_to_line_end<false>>>} },
{ alt('h'), "select to line begin", repeated<select<SelectMode::Replace, select_to_line_begin<false>>> }, { {alt('h')}, {"select to line begin", repeated<select<SelectMode::Replace, select_to_line_begin<false>>>} },
{ Key::Home, "select to line begin", repeated<select<SelectMode::Replace, select_to_line_begin<false>>> }, { {Key::Home}, {"select to line begin", repeated<select<SelectMode::Replace, select_to_line_begin<false>>>} },
{ alt('H'), "extend to line begin", repeated<select<SelectMode::Extend, select_to_line_begin<false>>> }, { {alt('H')}, {"extend to line begin", repeated<select<SelectMode::Extend, select_to_line_begin<false>>>} },
{ 'x', "select line", repeated<select<SelectMode::Replace, select_line>> }, { {'x'}, {"select line", repeated<select<SelectMode::Replace, select_line>>} },
{ 'X', "extend line", repeated<select<SelectMode::Extend, select_line>> }, { {'X'}, {"extend line", repeated<select<SelectMode::Extend, select_line>>} },
{ alt('x'), "extend selections to whole lines", select<SelectMode::Replace, select_lines> }, { {alt('x')}, {"extend selections to whole lines", select<SelectMode::Replace, select_lines>} },
{ alt('X'), "crop selections to whole lines", select<SelectMode::Replace, trim_partial_lines> }, { {alt('X')}, {"crop selections to whole lines", select<SelectMode::Replace, trim_partial_lines>} },
{ 'm', "select to matching character", select<SelectMode::Replace, select_matching> }, { {'m'}, {"select to matching character", select<SelectMode::Replace, select_matching>} },
{ 'M', "extend to matching character", select<SelectMode::Extend, select_matching> }, { {'M'}, {"extend to matching character", select<SelectMode::Extend, select_matching>} },
{ '/', "select next given regex match", search<SelectMode::Replace, Forward> }, { {'/'}, {"select next given regex match", search<SelectMode::Replace, Forward>} },
{ '?', "extend with next given regex match", search<SelectMode::Extend, Forward> }, { {'?'}, {"extend with next given regex match", search<SelectMode::Extend, Forward>} },
{ alt('/'), "select previous given regex match", search<SelectMode::Replace, Backward> }, { {alt('/')}, {"select previous given regex match", search<SelectMode::Replace, Backward>} },
{ alt('?'), "extend with previous given regex match", search<SelectMode::Extend, Backward> }, { {alt('?')}, {"extend with previous given regex match", search<SelectMode::Extend, Backward>} },
{ 'n', "select next current search pattern match", search_next<SelectMode::Replace, Forward> }, { {'n'}, {"select next current search pattern match", search_next<SelectMode::Replace, Forward>} },
{ 'N', "extend with next current search pattern match", search_next<SelectMode::Append, Forward> }, { {'N'}, {"extend with next current search pattern match", search_next<SelectMode::Append, Forward>} },
{ alt('n'), "select previous current search pattern match", search_next<SelectMode::Replace, Backward> }, { {alt('n')}, {"select previous current search pattern match", search_next<SelectMode::Replace, Backward>} },
{ alt('N'), "extend with previous current search pattern match", search_next<SelectMode::Append, Backward> }, { {alt('N')}, {"extend with previous current search pattern match", search_next<SelectMode::Append, Backward>} },
{ '*', "set search pattern to main selection content", use_selection_as_search_pattern<true> }, { {'*'}, {"set search pattern to main selection content", use_selection_as_search_pattern<true>} },
{ alt('*'), "set search pattern to main selection content, do not detect words", use_selection_as_search_pattern<false> }, { {alt('*')}, {"set search pattern to main selection content, do not detect words", use_selection_as_search_pattern<false>} },
{ 'u', "undo", undo }, { {'u'}, {"undo", undo} },
{ 'U', "redo", redo }, { {'U'}, {"redo", redo} },
{ alt('u'), "move backward in history", move_in_history<Direction::Backward> }, { {alt('u')}, {"move backward in history", move_in_history<Direction::Backward>} },
{ alt('U'), "move forward in history", move_in_history<Direction::Forward> }, { {alt('U')}, {"move forward in history", move_in_history<Direction::Forward>} },
{ alt('i'), "select inner object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd | ObjectFlags::Inner> }, { {alt('i')}, {"select inner object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd | ObjectFlags::Inner>} },
{ alt('a'), "select whole object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd> }, { {alt('a')}, {"select whole object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd>} },
{ '[', "select to object start", select_object<ObjectFlags::ToBegin> }, { {'['}, {"select to object start", select_object<ObjectFlags::ToBegin>} },
{ ']', "select to object end", select_object<ObjectFlags::ToEnd> }, { {']'}, {"select to object end", select_object<ObjectFlags::ToEnd>} },
{ '{', "extend to object start", select_object<ObjectFlags::ToBegin, SelectMode::Extend> }, { {'{'}, {"extend to object start", select_object<ObjectFlags::ToBegin, SelectMode::Extend>} },
{ '}', "extend to object end", select_object<ObjectFlags::ToEnd, SelectMode::Extend> }, { {'}'}, {"extend to object end", select_object<ObjectFlags::ToEnd, SelectMode::Extend>} },
{ alt('['), "select to inner object start", select_object<ObjectFlags::ToBegin | ObjectFlags::Inner> }, { {alt('[')}, {"select to inner object start", select_object<ObjectFlags::ToBegin | ObjectFlags::Inner>} },
{ alt(']'), "select to inner object end", select_object<ObjectFlags::ToEnd | ObjectFlags::Inner> }, { {alt(']')}, {"select to inner object end", select_object<ObjectFlags::ToEnd | ObjectFlags::Inner>} },
{ alt('{'), "extend to inner object start", select_object<ObjectFlags::ToBegin | ObjectFlags::Inner, SelectMode::Extend> }, { {alt('{')}, {"extend to inner object start", select_object<ObjectFlags::ToBegin | ObjectFlags::Inner, SelectMode::Extend>} },
{ alt('}'), "extend to inner object end", select_object<ObjectFlags::ToEnd | ObjectFlags::Inner, SelectMode::Extend> }, { {alt('}')}, {"extend to inner object end", select_object<ObjectFlags::ToEnd | ObjectFlags::Inner, SelectMode::Extend>} },
{ alt('j'), "join lines", join_lines }, { {alt('j')}, {"join lines", join_lines} },
{ alt('J'), "join lines and select spaces", join_lines_select_spaces }, { {alt('J')}, {"join lines and select spaces", join_lines_select_spaces} },
{ alt('k'), "keep selections matching given regex", keep<true> }, { {alt('k')}, {"keep selections matching given regex", keep<true>} },
{ alt('K'), "keep selections not matching given regex", keep<false> }, { {alt('K')}, {"keep selections not matching given regex", keep<false>} },
{ '$', "pipe each selection through shell command and keep the ones whose command succeed", keep_pipe }, { {'$'}, {"pipe each selection through shell command and keep the ones whose command succeed", keep_pipe} },
{ '<', "deindent", deindent<true> }, { {'<'}, {"deindent", deindent<true>} },
{ '>', "indent", indent<false> }, { {'>'}, {"indent", indent<false>} },
{ alt('>'), "indent, including empty lines", indent<true> }, { {alt('>')}, {"indent, including empty lines", indent<true>} },
{ alt('<'), "deindent, not including incomplete indent", deindent<false> }, { {alt('<')}, {"deindent, not including incomplete indent", deindent<false>} },
{ /*ctrl('i')*/Key::Tab, "jump forward in jump list",jump<Forward> }, // until we can distinguish tab a ctrl('i') { {/*ctrl('i')*/Key::Tab}, {"jump forward in jump list",jump<Forward>} }, // until we can distinguish tab a ctrl('i')
{ ctrl('o'), "jump backward in jump list", jump<Backward> }, { {ctrl('o')}, {"jump backward in jump list", jump<Backward>} },
{ ctrl('s'), "push current selections in jump list", push_selections }, { {ctrl('s')}, {"push current selections in jump list", push_selections} },
{ '\'', "rotate main selection", rotate_selections<Forward> }, { {'\''}, {"rotate main selection", rotate_selections<Forward>} },
{ alt('\''), "rotate main selection", rotate_selections<Backward> }, { {alt('\'')}, {"rotate main selection", rotate_selections<Backward>} },
{ alt('"'), "rotate selections content", rotate_selections_content }, { {alt('"')}, {"rotate selections content", rotate_selections_content} },
{ 'q', "replay recorded macro", replay_macro }, { {'q'}, {"replay recorded macro", replay_macro} },
{ 'Q', "start or end macro recording", start_or_end_macro_recording }, { {'Q'}, {"start or end macro recording", start_or_end_macro_recording} },
{ Key::Escape, "end macro recording", end_macro_recording }, { {Key::Escape}, {"end macro recording", end_macro_recording} },
{ '`', "convert to lower case in selections", for_each_codepoint<to_lower> }, { {'`'}, {"convert to lower case in selections", for_each_codepoint<to_lower>} },
{ '~', "convert to upper case in selections", for_each_codepoint<to_upper> }, { {'~'}, {"convert to upper case in selections", for_each_codepoint<to_upper>} },
{ alt('`'), "swap case in selections", for_each_codepoint<swap_case> }, { {alt('`')}, { "swap case in selections", for_each_codepoint<swap_case>} },
{ '&', "align selection cursors", align }, { {'&'}, {"align selection cursors", align} },
{ alt('&'), "copy indentation", copy_indent }, { {alt('&')}, {"copy indentation", copy_indent} },
{ '@', "convert tabs to spaces in selections", tabs_to_spaces }, { {'@'}, {"convert tabs to spaces in selections", tabs_to_spaces} },
{ alt('@'), "convert spaces to tabs in selections", spaces_to_tabs }, { {alt('@')}, {"convert spaces to tabs in selections", spaces_to_tabs} },
{ 'C', "copy selection on next lines", copy_selections_on_next_lines<Forward> }, { {'C'}, {"copy selection on next lines", copy_selections_on_next_lines<Forward>} },
{ alt('C'), "copy selection on previous lines", copy_selections_on_next_lines<Backward> }, { {alt('C')}, {"copy selection on previous lines", copy_selections_on_next_lines<Backward>} },
{ ',', "user mappings", exec_user_mappings }, { {','}, {"user mappings", exec_user_mappings} },
{ Key::Left, "move left", move<CharCount, Backward> }, { {Key::Left}, { "move left", move<CharCount, Backward>} },
{ Key::Down, "move down", move<LineCount, Forward> }, { {Key::Down}, { "move down", move<LineCount, Forward>} },
{ Key::Up, "move up", move<LineCount, Backward> }, { {Key::Up}, { "move up", move<LineCount, Backward>} },
{ Key::Right, "move right", move<CharCount, Forward> }, { {Key::Right}, {"move right", move<CharCount, Forward>} },
{ ctrl('b'), "scroll one page up", scroll<Backward > }, { {ctrl('b')}, {"scroll one page up", scroll<Backward >} },
{ ctrl('f'), "scroll one page down", scroll<Forward> }, { {ctrl('f')}, {"scroll one page down", scroll<Forward>} },
{ ctrl('u'), "scroll half a page up", scroll<Backward, true> }, { {ctrl('u')}, {"scroll half a page up", scroll<Backward, true>} },
{ ctrl('d'), "scroll half a page down", scroll<Forward, true> }, { {ctrl('d')}, {"scroll half a page down", scroll<Forward, true>} },
{ Key::PageUp, "scroll one page up", scroll<Backward> }, { {Key::PageUp}, { "scroll one page up", scroll<Backward>} },
{ Key::PageDown, "scroll one page down", scroll<Forward> }, { {Key::PageDown}, {"scroll one page down", scroll<Forward>} },
{ 'z', "restore selections from register", restore_selections<false> }, { {'z'}, {"restore selections from register", restore_selections<false>} },
{ alt('z'), "append selections from register", restore_selections<true> }, { {alt('z')}, {"append selections from register", restore_selections<true>} },
{ 'Z', "save selections to register", save_selections<false> }, { {'Z'}, {"save selections to register", save_selections<false>} },
{ alt('Z'), "append selections to register", save_selections<true> }, { {alt('Z')}, {"append selections to register", save_selections<true>} },
{ ctrl('l'), "force redraw", force_redraw }, { {ctrl('l')}, {"force redraw", force_redraw} },
}; };
KeyMap keymap = cmds;
} }

View File

@ -1,7 +1,7 @@
#ifndef normal_hh_INCLUDED #ifndef normal_hh_INCLUDED
#define normal_hh_INCLUDED #define normal_hh_INCLUDED
#include "array_view.hh" #include "hash_map.hh"
#include "keys.hh" #include "keys.hh"
#include "string.hh" #include "string.hh"
@ -16,15 +16,13 @@ struct NormalParams
char reg; char reg;
}; };
struct NormalCmdDesc struct NormalCmd
{ {
Key key;
StringView docstring; StringView docstring;
void (*func)(Context& context, NormalParams params); void (*func)(Context& context, NormalParams params);
}; };
using KeyMap = const ArrayView<NormalCmdDesc>; extern const HashMap<Key, NormalCmd> keymap;
extern KeyMap keymap;
} }