diff --git a/src/input_handler.cc b/src/input_handler.cc index a440dc1a..2e4a58f8 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -106,7 +106,16 @@ public: } auto it = keymap.find(key); if (it != keymap.end()) - it->second(context(), m_count); + { + if (context().options()["autoinfo"].get() >= 2 and context().has_ui()) + { + ColorPair col = get_color("Information"); + CharCoord pos = context().window().dimensions(); + pos.column -= 1; + context().ui().info_show(key_to_str(key), it->second.docstring, pos, col, MenuStyle::Prompt); + } + it->second.func(context(), m_count); + } m_count = 0; } diff --git a/src/normal.cc b/src/normal.cc index 307dfbf0..fffe8f36 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1231,150 +1231,150 @@ void move(Context& context, int count) KeyMap keymap = { - { 'h', move }, - { 'j', move }, - { 'k', move }, - { 'l', move }, + { 'h', { "move left", move } }, + { 'j', { "move down", move } }, + { 'k', { "move up", move } }, + { 'l', { "move right", move } }, - { 'H', move }, - { 'J', move }, - { 'K', move }, - { 'L', move }, + { 'H', { "extend left", move } }, + { 'J', { "extend down", move } }, + { 'K', { "extend up", move } }, + { 'L', { "extend right", move } }, - { 't', select_to_next_char }, - { 'f', select_to_next_char }, - { 'T', select_to_next_char }, - { 'F', select_to_next_char }, - { alt('t'), select_to_next_char }, - { alt('f'), select_to_next_char }, - { alt('T'), select_to_next_char }, - { alt('F'), select_to_next_char }, + { 't', { "select to next character", select_to_next_char } }, + { 'f', { "select to next character included", select_to_next_char } }, + { 'T', { "extend to next character", select_to_next_char } }, + { 'F', { "extend to next character included", select_to_next_char } }, + { alt('t'), { "select to previous character", select_to_next_char } }, + { alt('f'), { "select to previous character included", select_to_next_char } }, + { alt('T'), { "extend to previous character", select_to_next_char } }, + { alt('F'), { "extend to previous character included", select_to_next_char } }, - { 'd', erase_selections }, - { 'c', change }, - { 'i', enter_insert_mode }, - { 'I', enter_insert_mode }, - { 'a', enter_insert_mode }, - { 'A', enter_insert_mode }, - { 'o', enter_insert_mode }, - { 'O', enter_insert_mode }, - { 'r', replace_with_char }, + { 'd', { "erase selected text", erase_selections } }, + { 'c', { "change selected text", change } }, + { 'i', { "insert before selected text", enter_insert_mode } }, + { 'I', { "insert at line begin", enter_insert_mode } }, + { 'a', { "insert after selected text", enter_insert_mode } }, + { 'A', { "insert at line end", enter_insert_mode } }, + { 'o', { "insert on new line below", enter_insert_mode } }, + { 'O', { "insert on new line above", enter_insert_mode } }, + { 'r', { "replace with character", replace_with_char } }, - { 'g', goto_commands }, - { 'G', goto_commands }, + { 'g', { "go to location", goto_commands } }, + { 'G', { "extend to location", goto_commands } }, - { 'v', view_commands }, + { 'v', { "move view", view_commands } }, - { 'y', yank }, - { 'p', repeated(paste) }, - { 'P', repeated(paste) }, - { alt('p'), paste_all }, - { alt('P'), paste_all }, - { 'R', paste }, + { 'y', { "yank selected text", yank } }, + { 'p', { "paste after selected text", repeated(paste) } }, + { 'P', { "paste before selected text", repeated(paste) } }, + { alt('p'), { "paste every yanked selection after selected text", paste_all } }, + { alt('P'), { "paste every yanked selection before selected text", paste_all } }, + { 'R', { "replace selected text with yanked text", paste } }, - { 's', select_regex }, - { 'S', split_regex }, - { alt('s'), split_lines }, + { 's', { "select regex matches in selected text", select_regex } }, + { 'S', { "split selected text on regex matches", split_regex } }, + { alt('s'), { "split selected text on line ends", split_lines } }, - { '.', repeat_last_insert }, + { '.', { "repeat last insert command", repeat_last_insert } }, - { '%', [](Context& context, int) { select_buffer(context.selections()); } }, + { '%', { "select whole buffer", [](Context& context, int) { select_buffer(context.selections()); } } }, - { ':', command }, - { '|', pipe }, - { alt('|'), pipe }, - { ' ', [](Context& context, int count) { keep_selection(context.selections(), count ? count-1 : context.selections().main_index()); } }, - { alt(' '), [](Context& context, int count) { remove_selection(context.selections(), count ? count-1 : context.selections().main_index()); } }, - { ';', [](Context& context, int count) { clear_selections(context.selections()); } }, - { alt(';'), [](Context& context, int count) { flip_selections(context.selections()); } }, + { ':', { "enter command prompt", command } }, + { '|', { "pipe each selection through filter and replace with output", pipe } }, + { alt('|'), { "pipe each selection through filter and append with output", pipe } }, + { ' ', { "remove all selection except main", [](Context& context, int count) { keep_selection(context.selections(), count ? count-1 : context.selections().main_index()); } } }, + { alt(' '), { "remove main selection", [](Context& context, int count) { remove_selection(context.selections(), count ? count-1 : context.selections().main_index()); } } }, + { ';', { "reduce selections to their cursor", [](Context& context, int count) { clear_selections(context.selections()); } } }, + { alt(';'), { "swap selections cursor and anchor", [](Context& context, int count) { flip_selections(context.selections()); } } }, - { 'w', repeated(make_select(select_to_next_word)) }, - { 'e', repeated(make_select(select_to_next_word_end)) }, - { 'b', repeated(make_select(select_to_previous_word)) }, - { 'W', repeated(make_select(select_to_next_word)) }, - { 'E', repeated(make_select(select_to_next_word_end)) }, - { 'B', repeated(make_select(select_to_previous_word)) }, + { 'w', { "select to next word start", repeated(make_select(select_to_next_word)) } }, + { 'e', { "select to next word end", repeated(make_select(select_to_next_word_end)) } }, + { 'b', { "select to prevous word start", repeated(make_select(select_to_previous_word)) } }, + { 'W', { "extend to next word start", repeated(make_select(select_to_next_word)) } }, + { 'E', { "extend to next word end", repeated(make_select(select_to_next_word_end)) } }, + { 'B', { "extend to prevous word start", repeated(make_select(select_to_previous_word)) } }, - { alt('w'), repeated(make_select(select_to_next_word)) }, - { alt('e'), repeated(make_select(select_to_next_word_end)) }, - { alt('b'), repeated(make_select(select_to_previous_word)) }, - { alt('W'), repeated(make_select(select_to_next_word)) }, - { alt('E'), repeated(make_select(select_to_next_word_end)) }, - { alt('B'), repeated(make_select(select_to_previous_word)) }, + { alt('w'), { "select to next WORD start", repeated(make_select(select_to_next_word)) } }, + { alt('e'), { "select to next WORD end", repeated(make_select(select_to_next_word_end)) } }, + { alt('b'), { "select to prevous WORD start", repeated(make_select(select_to_previous_word)) } }, + { alt('W'), { "extend to next WORD start", repeated(make_select(select_to_next_word)) } }, + { alt('E'), { "extend to next WORD end", repeated(make_select(select_to_next_word_end)) } }, + { alt('B'), { "extend to prevous WORD start", repeated(make_select(select_to_previous_word)) } }, - { alt('l'), repeated(make_select(select_to_eol)) }, - { alt('L'), repeated(make_select(select_to_eol)) }, - { alt('h'), repeated(make_select(select_to_eol_reverse)) }, - { alt('H'), repeated(make_select(select_to_eol_reverse)) }, + { alt('l'), { "select to line end", repeated(make_select(select_to_eol)) } }, + { alt('L'), { "extend to line end", repeated(make_select(select_to_eol)) } }, + { alt('h'), { "select to line begin", repeated(make_select(select_to_eol_reverse)) } }, + { alt('H'), { "extend to line begin", repeated(make_select(select_to_eol_reverse)) } }, - { 'x', repeated(make_select(select_line)) }, - { 'X', repeated(make_select(select_line)) }, - { alt('x'), make_select(select_lines) }, - { alt('X'), make_select(trim_partial_lines) }, + { 'x', { "select line", repeated(make_select(select_line)) } }, + { 'X', { "extend line", repeated(make_select(select_line)) } }, + { alt('x'), { "extend selections to whole lines", make_select(select_lines) } }, + { alt('X'), { "crop selections to whole lines", make_select(trim_partial_lines) } }, - { 'm', make_select(select_matching) }, - { 'M', make_select(select_matching) }, + { 'm', { "select to matching character", make_select(select_matching) } }, + { 'M', { "extend to matching character", make_select(select_matching) } }, - { '/', search }, - { '?', search }, - { alt('/'), search }, - { alt('?'), search }, - { 'n', search_next }, - { 'N', search_next }, - { alt('n'), search_next }, - { alt('N'), search_next }, - { '*', use_selection_as_search_pattern }, - { alt('*'), use_selection_as_search_pattern }, + { '/', { "select next given regex match", search } }, + { '?', { "extend with next given regex match", search } }, + { alt('/'), { "select previous given regex match", search } }, + { alt('?'), { "extend with previous given regex match", search } }, + { 'n', { "select next current search pattern match", search_next } }, + { 'N', { "extend with next current search pattern match", search_next } }, + { alt('n'), { "select previous current search pattern match", search_next } }, + { alt('N'), { "extend with previous current search pattern match", search_next } }, + { '*', { "set search pattern to main selection content", use_selection_as_search_pattern } }, + { alt('*'), { "set search pattern to main selection content, do not detect words", use_selection_as_search_pattern } }, - { 'u', undo }, - { 'U', redo }, + { 'u', { "undo", undo } }, + { 'U', { "redo", redo } }, - { alt('i'), select_object }, - { alt('a'), select_object }, - { ']', select_object }, - { '[', select_object }, - { '{', select_object }, - { '}', select_object }, + { alt('i'), { "select inner object", select_object } }, + { alt('a'), { "select whole object", select_object } }, + { ']', { "select to object end", select_object } }, + { '[', { "select to object start", select_object } }, + { '}', { "extend to object end", select_object } }, + { '{', { "extend to object start", select_object } }, - { alt('j'), join }, - { alt('J'), join_select_spaces }, + { alt('j'), { "join lines", join } }, + { alt('J'), { "join lines and select spaces", join_select_spaces } }, - { alt('k'), keep }, - { alt('K'), keep }, - { '$', keep_pipe }, + { alt('k'), { "keep selections matching given regex", keep } }, + { alt('K'), { "keep selections not matching given regex", keep } }, + { '$', { "pipe each selection through shell command and keep the ones whose command succeed", keep_pipe } }, - { '<', deindent }, - { '>', indent }, - { alt('>'), indent }, - { alt('<'), deindent }, + { '<', { "deindent", deindent } }, + { '>', { "indent", indent } }, + { alt('>'), { "indent, including empty lines", indent } }, + { alt('<'), { "deindent, not including incomplete indent", deindent } }, - { ctrl('i'), jump }, - { ctrl('o'), jump }, - { ctrl('s'), save_selections }, + { ctrl('i'), { "jump forward in jump list",jump } }, + { ctrl('o'), { "jump backward in jump list", jump } }, + { ctrl('s'), { "push current selections in jump list", save_selections } }, - { alt('r'), rotate_selections }, - { alt('R'), rotate_selections_content }, + { alt('r'), { "rotate main selection", rotate_selections } }, + { alt('R'), { "rotate selections content", rotate_selections_content } }, - { 'q', replay_macro }, - { 'Q', start_or_end_macro_recording }, + { 'q', { "replay recorded macro", replay_macro } }, + { 'Q', { "start or end macro recording", start_or_end_macro_recording } }, - { '`', for_each_char }, - { '~', for_each_char }, - { alt('`'), for_each_char }, + { '`', { "convert to lower case in selections", for_each_char } }, + { '~', { "convert to upper case in selections", for_each_char } }, + { alt('`'), { "swap case in selections", for_each_char } }, - { '&', align }, - { alt('&'), copy_indent }, + { '&', { "align selection cursors", align } }, + { alt('&'), { "copy indentation", copy_indent } }, - { '@', tabs_to_spaces }, - { alt('@'), spaces_to_tabs }, + { '@', { "convert tabs to spaces in selections", tabs_to_spaces } }, + { alt('@'), { "convert spaces to tabs in selections", spaces_to_tabs } }, - { Key::Left, move }, - { Key::Down, move }, - { Key::Up, move }, - { Key::Right, move }, + { Key::Left, { "move left", move } }, + { Key::Down, { "move down", move } }, + { Key::Up, { "move up", move } }, + { Key::Right, { "move right", move } }, - { Key::PageUp, scroll }, - { Key::PageDown, scroll }, + { Key::PageUp, { "scroll one page up", scroll } }, + { Key::PageDown, { "scroll one page down", scroll } }, }; } diff --git a/src/normal.hh b/src/normal.hh index c35027ce..afd8840c 100644 --- a/src/normal.hh +++ b/src/normal.hh @@ -11,7 +11,13 @@ namespace Kakoune class Context; -using KeyMap = std::unordered_map>; +struct NormalCmdDesc +{ + const char* docstring; + std::function func; +}; + +using KeyMap = std::unordered_map; extern KeyMap keymap; }