diff --git a/clink/dll/clink_inputrc_base b/clink/dll/clink_inputrc_base index 30733e148..5fbeec560 100644 --- a/clink/dll/clink_inputrc_base +++ b/clink/dll/clink_inputrc_base @@ -23,6 +23,7 @@ C-v: paste-from-clipboard C-q: reload-lua-state C-z: undo M-h: show-rl-help +M-C-h: show-rl-history M-C-c: copy-line-to-clipboard C-c: ctrl-c M-a: "..\\" diff --git a/clink/dll/exec.lua b/clink/dll/exec.lua index 2ec6e1091..a2f8446cb 100644 --- a/clink/dll/exec.lua +++ b/clink/dll/exec.lua @@ -145,4 +145,20 @@ end -------------------------------------------------------------------------------- clink.register_match_generator(exec_match_generator, 50) + +local function history_match_generator(text, first, last) + leading = rl_state.line_buffer:sub(1, last):lower() + if not leading:find("^!") then + return false + end + + idx = tonumber(leading:sub(2)) + line = clink.get_history_at(idx) + clink.add_match(line) + + return true +end +-------------------------------------------------------------------------------- +clink.register_match_generator(history_match_generator, 1) + -- vim: expandtab diff --git a/clink/dll/lua.c b/clink/dll/lua.c index 8444ae362..dbf52dd26 100644 --- a/clink/dll/lua.c +++ b/clink/dll/lua.c @@ -331,6 +331,30 @@ static int get_env(lua_State* state) return 1; } +//------------------------------------------------------------------------------ +static int get_history_at(lua_State* state) +{ + char* buffer; + + if (lua_gettop(state) == 0) + { + return 0; + } + + if (lua_isnil(state, 1)) + { + return 0; + } + + unsigned idx = lua_tonumber(state, 1); + HIST_ENTRY * hist = history_get(idx); + buffer = strdup(hist->line); + lua_pushstring(state, buffer); + free(buffer); + + return 1; +} + //------------------------------------------------------------------------------ static int get_env_var_names(lua_State* state) { @@ -662,6 +686,7 @@ lua_State* initialise_lua() { "get_console_aliases", get_console_aliases }, { "get_cwd", get_cwd }, { "get_env", get_env }, + { "get_history_at", get_history_at }, { "get_env_var_names", get_env_var_names }, { "get_host_process", get_host_process }, { "get_rl_variable", get_rl_variable }, diff --git a/clink/dll/rl_funcs.c b/clink/dll/rl_funcs.c index f98c476d0..148a8f9e8 100644 --- a/clink/dll/rl_funcs.c +++ b/clink/dll/rl_funcs.c @@ -25,6 +25,7 @@ //------------------------------------------------------------------------------ void enter_scroll_mode(int); int show_rl_help(int, int); +int show_rl_history(int, int); int get_clink_setting_int(const char*); //------------------------------------------------------------------------------ @@ -254,6 +255,7 @@ void clink_register_rl_funcs() rl_add_funmap_entry("page-up", page_up); rl_add_funmap_entry("up-directory", up_directory); rl_add_funmap_entry("show-rl-help", show_rl_help); + rl_add_funmap_entry("show-rl-history", show_rl_history); rl_add_funmap_entry("copy-line-to-clipboard", copy_line_to_clipboard); rl_add_funmap_entry("expand-env-vars", expand_env_vars); } diff --git a/clink/dll/rl_help.c b/clink/dll/rl_help.c index 71a1f793e..2ba3902fe 100644 --- a/clink/dll/rl_help.c +++ b/clink/dll/rl_help.c @@ -192,3 +192,32 @@ int show_rl_help(int count, int invoking_key) free(collector); return 0; } + +#define MAX_HIST_LENGTH 1000 +//------------------------------------------------------------------------------ +int show_rl_history(int count, int invoking_key) +{ + HISTORY_STATE *hist = history_get_history_state(); + int max = 16; + int length = min(hist->length, MAX_HIST_LENGTH); + char* collector[MAX_HIST_LENGTH]; + + int longest = 1; + for (int i = 0; i < length; ++i) { + HIST_ENTRY* h = hist->entries[i]; + size_t line_len = strlen(h->line) + strlen("1000: ") + 1; + char * line = malloc(line_len); + sprintf_s(line, line_len, "%4d: %s", i + 1, h->line); + collector[i] = line; + longest = max(longest, strlen(h->line)); + } + + // Display the matches. + rl_display_match_list(collector, length - 1, longest); + rl_forced_update_display(); + + for (int i = 0; i < length; ++i) { + free(collector[i]); + } + return 0; +}