[PATCH 0/1] MR8467: conhost: Implement F1 and F3 support for history retrieval.
F1 and F3 allow partial retrieval of previous entry from console history. They are used as shortcuts such that if the following were entered at the command line: md tmptmp cd <F3> F3 will retrieve the previous line from history past the cursor position, and be auto-completed to "cd tmptmp". F1 works in a similar fashion, but with one character at a time. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8467
From: Joe Souza <jsouza(a)yahoo.com> --- programs/conhost/conhost.c | 70 +++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 89c030e86c8..44d24ab30f9 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -774,6 +774,56 @@ static void edit_line_find_in_history( struct console *console ) while (ctx->history_index != start_pos); } +static void edit_line_copy_from_hist( struct console *console, int copycount ) +{ + if (console->edit_line.history_index) + { + int index = console->edit_line.history_index - 1; + struct edit_line *ctx = &console->edit_line; + WCHAR *line = edit_line_history(console, index); + size_t len = line ? lstrlenW(line) : 0; + rsize_t ccount = (copycount > 0) ? copycount : _TRUNCATE; + + if (len > ctx->cursor) + { + WCHAR *tmp = malloc( (len + 1) * sizeof(WCHAR) ); + if (!tmp) + { + ctx->status = STATUS_NO_MEMORY; + return; + } + + /* Copy current line to our work buffer. */ + wcsncpy_s(tmp, len + 1, ctx->buf, _TRUNCATE); + /* Overwrite the string in the work buffer starting at the cursor, with the + string from history. */ + wcsncpy_s(&tmp[ctx->cursor], len - ctx->cursor + 1, &line[ctx->cursor], ccount); + len = lstrlenW(tmp); + + /* Clean the screen. */ + edit_line_delete(console, 0, ctx->len); + ctx->cursor = 0; + /* Insert new string. */ + if (edit_line_grow(console, len + 1)) + { + edit_line_insert( console, tmp, len ); + } + free(tmp); + } + free(line); + } +} + +static void edit_line_copy_one_from_hist( struct console *console ) +{ + edit_line_copy_from_hist(console, 1); +} + +static void edit_line_copy_all_from_hist( struct console *console ) +{ + edit_line_copy_from_hist(console, -1); +} + static void edit_line_move_left( struct console *console ) { if (console->edit_line.cursor > 0) console->edit_line.cursor--; @@ -1137,15 +1187,17 @@ static const struct edit_line_key_map emacs_key_map[] = static const struct edit_line_key_entry win32_std_key_map[] = { - { VK_LEFT, edit_line_move_left }, - { VK_RIGHT, edit_line_move_right }, - { VK_HOME, edit_line_move_home }, - { VK_END, edit_line_move_end }, - { VK_UP, edit_line_move_to_prev_hist }, - { VK_DOWN, edit_line_move_to_next_hist }, - { VK_INSERT, edit_line_toggle_insert }, - { VK_F8, edit_line_find_in_history }, - { VK_ESCAPE, edit_line_clear }, + { VK_LEFT, edit_line_move_left }, + { VK_RIGHT, edit_line_move_right }, + { VK_HOME, edit_line_move_home }, + { VK_END, edit_line_move_end }, + { VK_UP, edit_line_move_to_prev_hist }, + { VK_DOWN, edit_line_move_to_next_hist }, + { VK_INSERT, edit_line_toggle_insert }, + { VK_F8, edit_line_find_in_history }, + { VK_ESCAPE, edit_line_clear }, + { VK_F1, edit_line_copy_one_from_hist }, + { VK_F3, edit_line_copy_all_from_hist }, { 0 } }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8467
didn't look in details yet, but I don't see the need for an intermediate buffer. you just need to edit_line_delete( console, ctx-\>cursor, ctx-\>len ); to clear edit line after cursor, then insert history line + ctx-\>cursor, length 1 or til end of line. also quick testing on windows rather suggests that's the current_history line that should be used instead of last line in history I didn't check if history is modified by these operations -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8467#note_108454
participants (3)
-
eric pouech (@epo) -
Joe Souza -
Joe Souza (@JoeS209)