diff --git a/src/core/wee-command.c b/src/core/wee-command.c index bd41b2b..6ef5e1c 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -2356,6 +2356,14 @@ COMMAND_CALLBACK(input) gui_input_history_global_previous (buffer); else if (string_strcasecmp (argv[1], "history_global_next") == 0) gui_input_history_global_next (buffer); + else if (string_strcasecmp (argv[1], "history_search_previous") == 0) + gui_input_history_local_search_previous (buffer); + else if (string_strcasecmp (argv[1], "history_search_next") == 0) + gui_input_history_local_search_next (buffer); + else if (string_strcasecmp (argv[1], "history_global_search_previous") == 0) + gui_input_history_global_search_previous (buffer); + else if (string_strcasecmp (argv[1], "history_global_search_next") == 0) + gui_input_history_global_search_next (buffer); else if (string_strcasecmp (argv[1], "jump_smart") == 0) gui_input_jump_smart (buffer); else if (string_strcasecmp (argv[1], "jump_last_buffer") == 0) @@ -5750,6 +5758,14 @@ command_init () "global history\n" " history_global_next: recall next command in global " "history\n" + " history_search_previous: search previous command " + "in current buffer history\n" + " history_search_next: search next command in current " + "buffer history\n" + " history_global_search_previous: search previous " + "command in global history\n" + " history_global_search_next: search next command " + "in global history\n" " jump_smart: jump to next buffer with activity\n" " jump_last_buffer: jump to last buffer\n" " jump_last_buffer_displayed: jump to last buffer " @@ -5785,6 +5801,8 @@ command_init () "move_previous_char|move_next_char|move_previous_word|" "move_next_word|history_previous|history_next|" "history_global_previous|history_global_next|" + "history_search_previous|history_search_next|" + "history_global_search_previous|history_global_search_next|" "jump_smart|jump_last_buffer|jump_previously_visited_buffer|" "jump_next_visited_buffer|hotlist_clear|grab_key|" "grab_key_command|grab_mouse|grab_mouse_area|set_unread|" diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c index 92393ac..e328ef8 100644 --- a/src/gui/curses/gui-curses-key.c +++ b/src/gui/curses/gui-curses-key.c @@ -132,6 +132,10 @@ gui_key_default_bindings (int context) BIND(/* ^down */ "meta-Ob", "/input history_global_next"); BIND(/* ^down */ "meta-OB", "/input history_global_next"); BIND(/* ^down */ "meta2-1;5B", "/input history_global_next"); + BIND(/* shift-up */ "meta2-1;2A", "/input history_search_previous"); + BIND(/* shift-down */ "meta2-1;2B", "/input history_search_next"); + BIND(/* shift-pgup */ "meta2-5;2~", "/input history_global_search_previous"); + BIND(/* shift-pgdn */ "meta2-6;2~", "/input history_global_search_next"); BIND(/* m-a */ "meta-a", "/input jump_smart"); BIND(/* m-j,m-l */ "meta-jmeta-l", "/input jump_last_buffer"); BIND(/* m-j,m-r */ "meta-jmeta-r", "/server raw"); diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c index 7c3d205..bd8f5f1 100644 --- a/src/gui/gui-input.c +++ b/src/gui/gui-input.c @@ -1039,34 +1039,50 @@ gui_input_move_next_word (struct t_gui_buffer *buffer) void gui_input_history_previous (struct t_gui_window *window, struct t_gui_history *history, - struct t_gui_history **ptr_history) + struct t_gui_history **ptr_history, + int search) { + struct t_gui_history *search_start; + if (!window->buffer->input) return; + search_start = *ptr_history; + if (*ptr_history) - { - if (!(*ptr_history)->next_history) - return; *ptr_history = (*ptr_history)->next_history; - } - if (!(*ptr_history)) + else *ptr_history = history; if (!(*ptr_history)) + { + *ptr_history = search_start; return; + } + + /* search */ + while (search && string_strncasecmp((*ptr_history)->text, + window->buffer->input_buffer, + window->buffer->input_buffer_pos)) + { + if (!(*ptr_history)->next_history) + { + *ptr_history = search_start; + return; + } + *ptr_history = (*ptr_history)->next_history; + } /* bash/readline like use of history */ if (window->buffer->input_buffer_size > 0) { - if ((*ptr_history)->prev_history) + if (search_start) { /* replace text in history with current input */ window->buffer->input_buffer[window->buffer->input_buffer_size] = '\0'; - if ((*ptr_history)->prev_history->text) - free ((*ptr_history)->prev_history->text); - (*ptr_history)->prev_history->text = - strdup (window->buffer->input_buffer); + if (search_start->text) + free (search_start->text); + search_start->text = strdup (window->buffer->input_buffer); } else { @@ -1081,7 +1097,9 @@ gui_input_history_previous (struct t_gui_window *window, window->buffer->input_buffer_length = utf8_strlen ((*ptr_history)->text); gui_input_optimize_size (window->buffer); - window->buffer->input_buffer_pos = window->buffer->input_buffer_length; + if ((!search) || + (window->buffer->input_buffer_length < window->buffer->input_buffer_pos)) + window->buffer->input_buffer_pos = window->buffer->input_buffer_length; window->buffer->input_buffer_1st_display = 0; strcpy (window->buffer->input_buffer, (*ptr_history)->text); gui_input_text_changed_modifier_and_signal (window->buffer, 0); @@ -1095,7 +1113,8 @@ gui_input_history_previous (struct t_gui_window *window, void gui_input_history_next (struct t_gui_window *window, struct t_gui_history *history, - struct t_gui_history **ptr_history) + struct t_gui_history **ptr_history, + int search) { int input_changed; @@ -1115,7 +1134,14 @@ gui_input_history_next (struct t_gui_window *window, free ((*ptr_history)->text); (*ptr_history)->text = strdup (window->buffer->input_buffer); - *ptr_history = (*ptr_history)->prev_history; + /* search */ + do + *ptr_history = (*ptr_history)->prev_history; + while (search && (*ptr_history) && + string_strncasecmp((*ptr_history)->text, + window->buffer->input_buffer, + window->buffer->input_buffer_pos)); + if (*ptr_history) { window->buffer->input_buffer_size = @@ -1130,8 +1156,12 @@ gui_input_history_next (struct t_gui_window *window, window->buffer->input_buffer_length = 0; } gui_input_optimize_size (window->buffer); - window->buffer->input_buffer_pos = - window->buffer->input_buffer_length; + + if ((!search) || (window->buffer->input_buffer_length < + window->buffer->input_buffer_pos)) + window->buffer->input_buffer_pos = + window->buffer->input_buffer_length; + window->buffer->input_buffer_1st_display = 0; if (*ptr_history) { @@ -1178,7 +1208,7 @@ gui_input_history_local_previous (struct t_gui_buffer *buffer) { gui_input_history_previous (window, window->buffer->history, - &(window->buffer->ptr_history)); + &(window->buffer->ptr_history), 0); } } @@ -1197,7 +1227,7 @@ gui_input_history_local_next (struct t_gui_buffer *buffer) { gui_input_history_next (window, window->buffer->history, - &(window->buffer->ptr_history)); + &(window->buffer->ptr_history), 0); } } @@ -1216,7 +1246,7 @@ gui_input_history_global_previous (struct t_gui_buffer *buffer) { gui_input_history_previous (window, history_global, - &history_global_ptr); + &history_global_ptr, 0); } } @@ -1235,7 +1265,85 @@ gui_input_history_global_next (struct t_gui_buffer *buffer) { gui_input_history_next (window, history_global, - &history_global_ptr); + &history_global_ptr, 0); + } +} + +/* + * gui_input_history_local_search_previous: search previous command in + * local history + * (default key: shift-up) + */ + +void +gui_input_history_local_search_previous (struct t_gui_buffer *buffer) +{ + struct t_gui_window *window; + + window = gui_window_search_with_buffer (buffer); + if (window) + { + gui_input_history_previous (window, + window->buffer->history, + &(window->buffer->ptr_history), 1); + } +} + +/* + * gui_input_history_local_search_next: search next command in local history + * (default key: shift-down) + */ + +void +gui_input_history_local_search_next (struct t_gui_buffer *buffer) +{ + struct t_gui_window *window; + + window = gui_window_search_with_buffer (buffer); + if (window) + { + gui_input_history_next (window, + window->buffer->history, + &(window->buffer->ptr_history), 1); + } +} + +/* + * gui_input_history_global_search_previous: search previous command in + * global history + * (default key: shift-pgup) + */ + +void +gui_input_history_global_search_previous (struct t_gui_buffer *buffer) +{ + struct t_gui_window *window; + + window = gui_window_search_with_buffer (buffer); + if (window) + { + gui_input_history_previous (window, + history_global, + &history_global_ptr, 1); + } +} + +/* + * gui_history_global_search_next: search next command in global history + * (default key: shift-pgdn) + */ + +void +gui_input_history_global_search_next (struct t_gui_buffer *buffer) +{ + struct t_gui_window *window; + + window = gui_window_search_with_buffer (buffer); + if (window) + { + gui_input_history_next (window, + history_global, + &history_global_ptr, 1); } } diff --git a/src/gui/gui-input.h b/src/gui/gui-input.h index 456b39f..e77a74f 100644 --- a/src/gui/gui-input.h +++ b/src/gui/gui-input.h @@ -65,6 +65,10 @@ extern void gui_input_history_local_previous (struct t_gui_buffer *buffer); extern void gui_input_history_local_next (struct t_gui_buffer *buffer); extern void gui_input_history_global_previous (struct t_gui_buffer *buffer); extern void gui_input_history_global_next (struct t_gui_buffer *buffer); +extern void gui_input_history_local_search_previous (struct t_gui_buffer *buffer); +extern void gui_input_history_local_search_next (struct t_gui_buffer *buffer); +extern void gui_input_history_global_search_previous (struct t_gui_buffer *buffer); +extern void gui_input_history_global_search_next (struct t_gui_buffer *buffer); extern void gui_input_jump_smart (struct t_gui_buffer *buffer); extern void gui_input_jump_last_buffer (struct t_gui_buffer *buffer); extern void gui_input_jump_last_buffer_displayed (struct t_gui_buffer *buffer);