Skip to content

Commit

Permalink
core: add incremental search in commands history (issue #2040)
Browse files Browse the repository at this point in the history
Changes:

- move key ctrl+r to ctrl+s
- add key ctrl+r to search in commands history
- add option `search_history` in command `/input`
- add key context "histsearch"
- add option weechat.look.buffer_search_history
- add buffer variables "text_search_direction", "text_search_history" and "text_search_ptr_history"
  • Loading branch information
flashcode committed Nov 7, 2023
1 parent 977fd3b commit 9e3d514
Show file tree
Hide file tree
Showing 22 changed files with 739 additions and 329 deletions.
1 change: 1 addition & 0 deletions ChangeLog.adoc
Expand Up @@ -15,6 +15,7 @@ For a list of important changes that require manual actions, please look at rele

New features::

* core: move key kbd:[Ctrl+r] to kbd:[Ctrl+s], add key kbd:[Ctrl+r] to search in commands history, add option `search_history` in command `/input`, add key context "histsearch", add option weechat.look.buffer_search_history, add buffer variables "text_search_direction", "text_search_history" and "text_search_ptr_history" (issue #2040)
* core: display only version with command `/version`, add options `-o` and `-ol` in command `/upgrade`
* core: add number of processes in command `/sys waitpid`
* core, alias, trigger: allow wildcard in commands `/bar`, `/item`, `/proxy`, `/alias` and `/trigger` (issue #1956)
Expand Down
9 changes: 6 additions & 3 deletions src/core/wee-command.c
Expand Up @@ -3525,6 +3525,8 @@ COMMAND_CALLBACK(input)
gui_input_search_text_here (buffer);
else if (string_strcmp (argv[1], "search_text") == 0)
gui_input_search_text (buffer);
else if (string_strcmp (argv[1], "search_history") == 0)
gui_input_search_history (buffer);
else if (string_strcmp (argv[1], "search_previous") == 0)
gui_input_search_previous (buffer);
else if (string_strcmp (argv[1], "search_next") == 0)
Expand Down Expand Up @@ -8481,6 +8483,7 @@ command_init ()
N_("> raw[complete_previous]: complete word with previous completion"),
N_("> raw[search_text_here]: search text in buffer at current position"),
N_("> raw[search_text]: search text in buffer"),
N_("> raw[search_history]: search text in command line history"),
N_("> raw[search_switch_case]: switch exact case for search"),
N_("> raw[search_switch_regex]: switch search type: string/regular expression"),
N_("> raw[search_switch_where]: switch search in messages/prefixes"),
Expand Down Expand Up @@ -8535,9 +8538,9 @@ command_init ()
N_("This command is used by key bindings or plugins.")),
"return || split_return || "
"complete_next || complete_previous || search_text_here || "
"search_text || search_switch_case || search_switch_regex || "
"search_switch_where || search_previous || search_next || "
"search_stop_here || search_stop || "
"search_text || search_history || search_switch_case || "
"search_switch_regex || search_switch_where || search_previous || "
"search_next || search_stop_here || search_stop || "
"delete_previous_char || delete_next_char || delete_previous_word || "
"delete_previous_word_whitespace || delete_next_word || "
"delete_beginning_of_line || delete_beginning_of_input || "
Expand Down
11 changes: 10 additions & 1 deletion src/core/wee-config.c
Expand Up @@ -89,7 +89,7 @@ struct t_config_section *weechat_config_section_buffer = NULL;
struct t_config_section *weechat_config_section_notify = NULL;
struct t_config_section *weechat_config_section_filter = NULL;
struct t_config_section *weechat_config_section_key[GUI_KEY_NUM_CONTEXTS] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
};

/* config, startup section */
Expand All @@ -114,6 +114,7 @@ struct t_config_option *config_look_buffer_auto_renumber = NULL;
struct t_config_option *config_look_buffer_notify_default = NULL;
struct t_config_option *config_look_buffer_position = NULL;
struct t_config_option *config_look_buffer_search_case_sensitive = NULL;
struct t_config_option *config_look_buffer_search_history = NULL;
struct t_config_option *config_look_buffer_search_force_default = NULL;
struct t_config_option *config_look_buffer_search_regex = NULL;
struct t_config_option *config_look_buffer_search_where = NULL;
Expand Down Expand Up @@ -3167,6 +3168,14 @@ config_weechat_init_options ()
N_("default text search in buffer: case sensitive or not"),
NULL, 0, 0, "off", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_buffer_search_history = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"buffer_search_history", "enum",
N_("default text search command line history: local (buffer) or "
"global history"),
"local|global", 0, 0, "local",
NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_buffer_search_force_default = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"buffer_search_force_default", "boolean",
Expand Down
7 changes: 7 additions & 0 deletions src/core/wee-config.h
Expand Up @@ -50,6 +50,12 @@ enum t_config_look_buffer_position
CONFIG_LOOK_BUFFER_POSITION_FIRST_GAP,
};

enum t_config_look_buffer_search_history
{
CONFIG_LOOK_BUFFER_SEARCH_HISTORY_LOCAL = 0,
CONFIG_LOOK_BUFFER_SEARCH_HISTORY_GLOBAL,
};

enum t_config_look_buffer_search_where
{
CONFIG_LOOK_BUFFER_SEARCH_PREFIX = 0,
Expand Down Expand Up @@ -165,6 +171,7 @@ extern struct t_config_option *config_look_buffer_auto_renumber;
extern struct t_config_option *config_look_buffer_notify_default;
extern struct t_config_option *config_look_buffer_position;
extern struct t_config_option *config_look_buffer_search_case_sensitive;
extern struct t_config_option *config_look_buffer_search_history;
extern struct t_config_option *config_look_buffer_search_force_default;
extern struct t_config_option *config_look_buffer_search_regex;
extern struct t_config_option *config_look_buffer_search_where;
Expand Down
11 changes: 1 addition & 10 deletions src/core/wee-upgrade.c
Expand Up @@ -546,16 +546,7 @@ upgrade_weechat_read_buffer (struct t_infolist *infolist)
}
}

/* text search */
ptr_buffer->text_search = infolist_integer (infolist, "text_search");
ptr_buffer->text_search_exact = infolist_integer (infolist,
"text_search_exact");
ptr_buffer->text_search_found = infolist_integer (infolist,
"text_search_found");
if (ptr_buffer->text_search_input)
free (ptr_buffer->text_search_input);
str = infolist_string (infolist, "text_search_input");
ptr_buffer->text_search_input = (str) ? strdup (str) : NULL;
/* text search is disabled after upgrade */

/* highlight options */
gui_buffer_set_highlight_words (
Expand Down
10 changes: 5 additions & 5 deletions src/gui/curses/gui-curses-chat.c
Expand Up @@ -1505,8 +1505,8 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
ptr_data = (message_with_tags) ?
message_with_tags : line->data->message;
message_with_search = NULL;
if ((window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
&& (window->buffer->text_search_where & GUI_TEXT_SEARCH_IN_MESSAGE)
if ((window->buffer->text_search == GUI_BUFFER_SEARCH_LINES)
&& (window->buffer->text_search_where & GUI_BUFFER_SEARCH_IN_MESSAGE)
&& (!window->buffer->text_search_regex
|| window->buffer->text_search_regex_compiled))
{
Expand Down Expand Up @@ -1695,7 +1695,7 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
else
{
/* display marker if line is matching user search */
if (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
if (window->buffer->text_search == GUI_BUFFER_SEARCH_LINES)
{
if (gui_line_search_text (window->buffer, line))
{
Expand Down Expand Up @@ -1765,8 +1765,8 @@ gui_chat_display_line_y (struct t_gui_window *window, struct t_gui_line *line,
}

/* emphasize text (if searching text) */
if ((window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
&& (window->buffer->text_search_where & GUI_TEXT_SEARCH_IN_MESSAGE)
if ((window->buffer->text_search == GUI_BUFFER_SEARCH_LINES)
&& (window->buffer->text_search_where & GUI_BUFFER_SEARCH_IN_MESSAGE)
&& (!window->buffer->text_search_regex
|| window->buffer->text_search_regex_compiled))
{
Expand Down
25 changes: 13 additions & 12 deletions src/gui/curses/gui-curses-key.c
Expand Up @@ -83,7 +83,8 @@ gui_key_default_bindings (int context, int create_option)
BIND("meta-return", "/input insert \\n");
BIND("tab", "/input complete_next");
BIND("shift-tab", "/input complete_previous");
BIND("ctrl-r", "/input search_text_here");
BIND("ctrl-r", "/input search_history");
BIND("ctrl-s", "/input search_text_here");
BIND("backspace", "/input delete_previous_char");
BIND("ctrl-_", "/input undo");
BIND("meta-_", "/input redo");
Expand Down Expand Up @@ -206,14 +207,17 @@ gui_key_default_bindings (int context, int create_option)
BIND(key_str, command);
}
}
else if (context == GUI_KEY_CONTEXT_SEARCH)
else if ((context == GUI_KEY_CONTEXT_SEARCH)
|| (context == GUI_KEY_CONTEXT_HISTSEARCH))
{
BIND("return", "/input search_stop_here");
BIND("ctrl-q", "/input search_stop");
BIND("meta-c", "/input search_switch_case");
BIND("ctrl-r", "/input search_switch_regex");
BIND("ctrl-x", "/input search_switch_regex");
BIND("tab", "/input search_switch_where");
BIND("ctrl-r", "/input search_previous");
BIND("up", "/input search_previous");
BIND("ctrl-s", "/input search_next");
BIND("down", "/input search_next");
}
else if (context == GUI_KEY_CONTEXT_CURSOR)
Expand Down Expand Up @@ -414,7 +418,7 @@ gui_key_flush (int paste)
gui_key_last_key_pressed_sent = i;
}

if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
if (gui_current_window->buffer->text_search != GUI_BUFFER_SEARCH_DISABLED)
input_old = (gui_current_window->buffer->input_buffer) ?
strdup (gui_current_window->buffer->input_buffer) : strdup ("");
else
Expand All @@ -434,17 +438,17 @@ gui_key_flush (int paste)
undo_done = 1;
}

/* incremental text search in buffer */
/* incremental text search in buffer lines or command line history */
if ((old_buffer == gui_current_window->buffer)
&& (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
&& ((gui_current_window->buffer->text_search == GUI_BUFFER_SEARCH_LINES)
|| (gui_current_window->buffer->text_search == GUI_BUFFER_SEARCH_HISTORY))
&& ((input_old == NULL)
|| (gui_current_window->buffer->input_buffer == NULL)
|| (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0)))
{
/*
* if following conditions are all true, then do not search
* again (search will not find any result and can take some time
* on a buffer with many lines):
* again (search will not find any result and can take some time):
* - old search was not successful
* - searching a string (not a regex)
* - current input is longer than old input
Expand All @@ -460,10 +464,7 @@ gui_key_flush (int paste)
&& (strncmp (gui_current_window->buffer->input_buffer, input_old,
strlen (input_old)) == 0))
{
/*
* do not search text in buffer, just alert about text not
* found
*/
/* do not search text, just alert about text not found */
if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert))
{
fprintf (stderr, "\a");
Expand Down
3 changes: 1 addition & 2 deletions src/gui/curses/gui-curses-mouse.c
Expand Up @@ -461,8 +461,7 @@ gui_mouse_event_end ()
else if (!gui_key_debug)
{
/* execute command (if found) */
(void) gui_key_focus (mouse_key,
GUI_KEY_CONTEXT_MOUSE);
(void) gui_key_focus (mouse_key, GUI_KEY_CONTEXT_MOUSE);
}
if (!bare_event)
gui_mouse_event_reset ();
Expand Down
86 changes: 68 additions & 18 deletions src/gui/gui-bar-item.c
Expand Up @@ -49,6 +49,7 @@
#include "gui-completion.h"
#include "gui-cursor.h"
#include "gui-filter.h"
#include "gui-history.h"
#include "gui-hotlist.h"
#include "gui-key.h"
#include "gui-line.h"
Expand Down Expand Up @@ -847,7 +848,8 @@ gui_bar_item_input_search_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_hashtable *extra_info)
{
char str_search[1024];
char str_search[1024], str_where[256];
int text_found;

/* make C compiler happy */
(void) pointer;
Expand All @@ -856,25 +858,52 @@ gui_bar_item_input_search_cb (const void *pointer, void *data,
(void) window;
(void) extra_info;

if (!buffer)
if (!buffer || (buffer->text_search == GUI_BUFFER_SEARCH_DISABLED))
return NULL;

if (buffer->text_search == GUI_TEXT_SEARCH_DISABLED)
return NULL;
str_where[0] = '\0';

snprintf (str_search, sizeof (str_search), "%s%s (%s %s,%s%s%s)",
(buffer->text_search_found
|| !buffer->input_buffer
|| !buffer->input_buffer[0]) ?
GUI_COLOR_CUSTOM_BAR_FG :
gui_color_get_custom (gui_color_get_name (CONFIG_COLOR(config_color_input_text_not_found))),
_("Search"),
(buffer->text_search_exact) ? "==" : "~",
(buffer->text_search_regex) ? "regex" : "str",
(buffer->text_search_where & GUI_TEXT_SEARCH_IN_PREFIX) ? "pre" : "",
((buffer->text_search_where & GUI_TEXT_SEARCH_IN_PREFIX)
&& (buffer->text_search_where & GUI_TEXT_SEARCH_IN_MESSAGE)) ? "|" : "",
(buffer->text_search_where & GUI_TEXT_SEARCH_IN_MESSAGE) ? "msg" : "");
switch (buffer->text_search)
{
case GUI_BUFFER_SEARCH_DISABLED:
return NULL;
case GUI_BUFFER_SEARCH_LINES:
snprintf (
str_where, sizeof (str_where),
"%s%s%s",
(buffer->text_search_where & GUI_BUFFER_SEARCH_IN_PREFIX) ? "pre" : "",
((buffer->text_search_where & GUI_BUFFER_SEARCH_IN_PREFIX)
&& (buffer->text_search_where & GUI_BUFFER_SEARCH_IN_MESSAGE)) ? "|" : "",
(buffer->text_search_where & GUI_BUFFER_SEARCH_IN_MESSAGE) ? "msg" : "");
break;
case GUI_BUFFER_SEARCH_HISTORY:
snprintf (str_where, sizeof (str_where),
"%s",
(buffer->text_search_history == GUI_BUFFER_SEARCH_HISTORY_LOCAL) ?
/* TRANSLATORS: search in "local" history */
_("local") :
/* TRANSLATORS: search in "global" history */
_("global"));
break;
case GUI_BUFFER_NUM_SEARCH:
return NULL;
}

text_found = (buffer->text_search_found
|| !buffer->input_buffer
|| !buffer->input_buffer[0]);

snprintf (
str_search, sizeof (str_search),
"%s%s (%s %s,%s)",
(text_found) ?
GUI_COLOR_CUSTOM_BAR_FG :
gui_color_get_custom (gui_color_get_name (CONFIG_COLOR(config_color_input_text_not_found))),
(buffer->text_search == GUI_BUFFER_SEARCH_LINES) ?
_("Search lines") : _("Search command"),
(buffer->text_search_exact) ? "==" : "~",
(buffer->text_search_regex) ? "regex" : "str",
str_where);

return strdup (str_search);
}
Expand Down Expand Up @@ -993,6 +1022,26 @@ gui_bar_item_input_text_cb (const void *pointer, void *data,
ptr_input = ptr_input2;
}

/* add matching text found in history (in history search mode) */
if ((buffer->text_search == GUI_BUFFER_SEARCH_HISTORY)
&& buffer->text_search_ptr_history)
{
length = strlen (ptr_input) + 16
+ ((buffer->text_search_ptr_history->text) ?
strlen (buffer->text_search_ptr_history->text) : 0);
buf = malloc (length);
if (buf)
{
snprintf (buf, length,
"%s => %s",
ptr_input,
(buffer->text_search_ptr_history->text) ?
buffer->text_search_ptr_history->text : "");
free (ptr_input);
ptr_input = buf;
}
}

/*
* transform '\n' to '\r' so the newlines are displayed as real new lines
* instead of spaces
Expand Down Expand Up @@ -2275,7 +2324,8 @@ gui_bar_item_init ()
gui_bar_item_new (NULL,
gui_bar_item_names[GUI_BAR_ITEM_INPUT_TEXT],
&gui_bar_item_input_text_cb, NULL, NULL);
gui_bar_item_hook_signal ("window_switch;buffer_switch;input_text_*",
gui_bar_item_hook_signal ("window_switch;buffer_switch;input_search;"
"input_text_*",
gui_bar_item_names[GUI_BAR_ITEM_INPUT_TEXT]);

/* time */
Expand Down

0 comments on commit 9e3d514

Please sign in to comment.