diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/curses/gui-curses-chat.c | 10 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-key.c | 25 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-mouse.c | 3 | ||||
-rw-r--r-- | src/gui/gui-bar-item.c | 86 | ||||
-rw-r--r-- | src/gui/gui-buffer.c | 31 | ||||
-rw-r--r-- | src/gui/gui-buffer.h | 55 | ||||
-rw-r--r-- | src/gui/gui-history.c | 251 | ||||
-rw-r--r-- | src/gui/gui-history.h | 2 | ||||
-rw-r--r-- | src/gui/gui-input.c | 154 | ||||
-rw-r--r-- | src/gui/gui-input.h | 2 | ||||
-rw-r--r-- | src/gui/gui-key.c | 22 | ||||
-rw-r--r-- | src/gui/gui-key.h | 1 | ||||
-rw-r--r-- | src/gui/gui-line.c | 4 | ||||
-rw-r--r-- | src/gui/gui-window.c | 358 | ||||
-rw-r--r-- | src/gui/gui-window.h | 4 |
15 files changed, 696 insertions, 312 deletions
diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index bc2fb99c6..cfdfd2f9b 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -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)) { @@ -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)) { @@ -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)) { diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c index cb5279ff0..397605d49 100644 --- a/src/gui/curses/gui-curses-key.c +++ b/src/gui/curses/gui-curses-key.c @@ -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"); @@ -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) @@ -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 @@ -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 @@ -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"); diff --git a/src/gui/curses/gui-curses-mouse.c b/src/gui/curses/gui-curses-mouse.c index d463ec9ee..c0c82e47d 100644 --- a/src/gui/curses/gui-curses-mouse.c +++ b/src/gui/curses/gui-curses-mouse.c @@ -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 (); diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c index d0db26683..23d512818 100644 --- a/src/gui/gui-bar-item.c +++ b/src/gui/gui-bar-item.c @@ -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" @@ -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; @@ -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); } @@ -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 @@ -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 */ diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index f89b553f2..598d72bae 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -101,8 +101,8 @@ char *gui_buffer_properties_get_integer[] = "input", "input_get_unknown_commands", "input_get_empty", "input_multiline", "input_size", "input_length", "input_pos", "input_1st_display", "num_history", "text_search", - "text_search_exact", "text_search_regex", "text_search_where", - "text_search_found", + "text_search_direction", "text_search_exact", "text_search_regex", + "text_search_where", "text_search_history", "text_search_found", NULL }; char *gui_buffer_properties_get_string[] = @@ -113,8 +113,8 @@ char *gui_buffer_properties_get_string[] = NULL }; char *gui_buffer_properties_get_pointer[] = -{ "plugin", "text_search_regex_compiled", "highlight_disable_regex_compiled", - "highlight_regex_compiled", +{ "plugin", "text_search_regex_compiled", "text_search_ptr_history", + "highlight_disable_regex_compiled", "highlight_regex_compiled", NULL }; char *gui_buffer_properties_set[] = @@ -871,12 +871,15 @@ gui_buffer_new_props (struct t_weechat_plugin *plugin, new_buffer->num_history = 0; /* text search */ - new_buffer->text_search = GUI_TEXT_SEARCH_DISABLED; + new_buffer->text_search = GUI_BUFFER_SEARCH_DISABLED; + new_buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_BACKWARD; new_buffer->text_search_exact = 0; new_buffer->text_search_regex = 0; new_buffer->text_search_regex_compiled = NULL; new_buffer->text_search_where = 0; + new_buffer->text_search_history = GUI_BUFFER_SEARCH_HISTORY_NONE; new_buffer->text_search_found = 0; + new_buffer->text_search_ptr_history = NULL; new_buffer->text_search_input = NULL; /* highlight */ @@ -1391,12 +1394,16 @@ gui_buffer_get_integer (struct t_gui_buffer *buffer, const char *property) return buffer->num_history; else if (strcmp (property, "text_search") == 0) return buffer->text_search; + else if (strcmp (property, "text_search_direction") == 0) + return buffer->text_search_direction; else if (strcmp (property, "text_search_exact") == 0) return buffer->text_search_exact; else if (strcmp (property, "text_search_regex") == 0) return buffer->text_search_regex; else if (strcmp (property, "text_search_where") == 0) return buffer->text_search_where; + else if (strcmp (property, "text_search_history") == 0) + return buffer->text_search_history; else if (strcmp (property, "text_search_found") == 0) return buffer->text_search_found; @@ -1468,6 +1475,8 @@ gui_buffer_get_pointer (struct t_gui_buffer *buffer, const char *property) return buffer->plugin; else if (strcmp (property, "text_search_regex_compiled") == 0) return buffer->text_search_regex_compiled; + else if (strcmp (property, "text_search_ptr_history") == 0) + return buffer->text_search_ptr_history; else if (strcmp (property, "highlight_disable_regex_compiled") == 0) return buffer->highlight_disable_regex_compiled; else if (strcmp (property, "highlight_regex_compiled") == 0) @@ -4981,11 +4990,14 @@ gui_buffer_hdata_buffer_cb (const void *pointer, void *data, HDATA_VAR(struct t_gui_buffer, ptr_history, POINTER, 0, NULL, "history"); HDATA_VAR(struct t_gui_buffer, num_history, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search, INTEGER, 0, NULL, NULL); + HDATA_VAR(struct t_gui_buffer, text_search_direction, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search_exact, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search_regex, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search_regex_compiled, POINTER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search_where, INTEGER, 0, NULL, NULL); + HDATA_VAR(struct t_gui_buffer, text_search_history, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, text_search_found, INTEGER, 0, NULL, NULL); + HDATA_VAR(struct t_gui_buffer, text_search_ptr_history, POINTER, 0, NULL, "history"); HDATA_VAR(struct t_gui_buffer, text_search_input, STRING, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, highlight_words, STRING, 0, NULL, NULL); HDATA_VAR(struct t_gui_buffer, highlight_disable_regex, STRING, 0, NULL, NULL); @@ -5190,6 +5202,8 @@ gui_buffer_add_to_infolist (struct t_infolist *infolist, return 0; if (!infolist_new_var_integer (ptr_item, "text_search", buffer->text_search)) return 0; + if (!infolist_new_var_integer (ptr_item, "text_search_direction", buffer->text_search_direction)) + return 0; if (!infolist_new_var_integer (ptr_item, "text_search_exact", buffer->text_search_exact)) return 0; if (!infolist_new_var_integer (ptr_item, "text_search_regex", buffer->text_search_regex)) @@ -5198,8 +5212,12 @@ gui_buffer_add_to_infolist (struct t_infolist *infolist, return 0; if (!infolist_new_var_integer (ptr_item, "text_search_where", buffer->text_search_where)) return 0; + if (!infolist_new_var_integer (ptr_item, "text_search_history", buffer->text_search_history)) + return 0; if (!infolist_new_var_integer (ptr_item, "text_search_found", buffer->text_search_found)) return 0; + if (!infolist_new_var_pointer (ptr_item, "text_search_ptr_history", buffer->text_search_ptr_history)) + return 0; if (!infolist_new_var_string (ptr_item, "text_search_input", buffer->text_search_input)) return 0; if (!infolist_new_var_string (ptr_item, "highlight_words", buffer->highlight_words)) @@ -5424,11 +5442,14 @@ gui_buffer_print_log () log_printf (" ptr_history . . . . . . : 0x%lx", ptr_buffer->ptr_history); log_printf (" num_history . . . . . . : %d", ptr_buffer->num_history); log_printf (" text_search . . . . . . . . . . : %d", ptr_buffer->text_search); + log_printf (" text_search_direction . . . . . : %d", ptr_buffer->text_search_direction); log_printf (" text_search_exact . . . . . . . : %d", ptr_buffer->text_search_exact); log_printf (" text_search_regex . . . . . . . : %d", ptr_buffer->text_search_regex); log_printf (" text_search_regex_compiled. . . : 0x%lx", ptr_buffer->text_search_regex_compiled); log_printf (" text_search_where . . . . . . . : %d", ptr_buffer->text_search_where); + log_printf (" text_search_history . . . . . . : %d", ptr_buffer->text_search_history); log_printf (" text_search_found . . . . . . . : %d", ptr_buffer->text_search_found); + log_printf (" text_search_ptr_history . . . . : 0x%lx", ptr_buffer->text_search_ptr_history); log_printf (" text_search_input . . . . . . . : '%s'", ptr_buffer->text_search_input); log_printf (" highlight_words . . . . . . . . : '%s'", ptr_buffer->highlight_words); log_printf (" highlight_disable_regex . . . . : '%s'", ptr_buffer->highlight_disable_regex); diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 6b3357ab9..969e25a4d 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -46,6 +46,32 @@ enum t_gui_buffer_notify GUI_BUFFER_NUM_NOTIFY, }; +enum t_gui_buffer_search +{ + GUI_BUFFER_SEARCH_DISABLED = 0, + GUI_BUFFER_SEARCH_LINES, /* search in buffer lines */ + GUI_BUFFER_SEARCH_HISTORY, /* search in buffer command line history */ + /* number of search modes */ + GUI_BUFFER_NUM_SEARCH, +}; + +enum t_gui_buffer_search_dir +{ + GUI_BUFFER_SEARCH_DIR_BACKWARD = 0, + GUI_BUFFER_SEARCH_DIR_FORWARD, + /* number of search directions */ + GUI_BUFFER_NUM_SEARCH_DIR, +}; + +enum t_gui_buffer_search_history +{ + GUI_BUFFER_SEARCH_HISTORY_NONE = 0, + GUI_BUFFER_SEARCH_HISTORY_LOCAL, + GUI_BUFFER_SEARCH_HISTORY_GLOBAL, + /* number of search history */ + GUI_BUFFER_NUM_SEARCH_HISTORY, +}; + #define GUI_BUFFER_TYPE_DEFAULT GUI_BUFFER_TYPE_FORMATTED #define GUI_BUFFER_MAIN "weechat" @@ -54,12 +80,9 @@ enum t_gui_buffer_notify #define GUI_BUFFER_NUMBER_MAX (INT_MAX - 10000) -#define GUI_TEXT_SEARCH_DISABLED 0 -#define GUI_TEXT_SEARCH_BACKWARD 1 -#define GUI_TEXT_SEARCH_FORWARD 2 - -#define GUI_TEXT_SEARCH_IN_MESSAGE 1 -#define GUI_TEXT_SEARCH_IN_PREFIX 2 +/* search where in buffer lines? */ +#define GUI_BUFFER_SEARCH_IN_MESSAGE (1 << 0) +#define GUI_BUFFER_SEARCH_IN_PREFIX (1 << 1) #define GUI_BUFFER_INPUT_BLOCK_SIZE 256 @@ -189,14 +212,18 @@ struct t_gui_buffer struct t_gui_history *ptr_history; /* current command in history */ int num_history; /* number of commands in history */ - /* text search */ - int text_search; /* text search type */ - int text_search_exact; /* exact search (case sensitive) ? */ - int text_search_regex; /* search with a regex */ - regex_t *text_search_regex_compiled; /* regex used to search */ - int text_search_where; /* search where? prefix and/or msg */ - int text_search_found; /* 1 if text found, otherwise 0 */ - char *text_search_input; /* input saved before text search */ + /* text search (in buffer lines or command line history) */ + enum t_gui_buffer_search text_search; /* text search type */ + enum t_gui_buffer_search_dir text_search_direction; + /* search dir.: backward/forward */ + int text_search_exact; /* case sensitive search? */ + int text_search_regex; /* search with a regex */ + regex_t *text_search_regex_compiled; /* regex used to search */ + int text_search_where; /* prefix and/or msg */ + enum t_gui_buffer_search_history text_search_history; /* local/global */ + int text_search_found; /* 1 if text found, otherwise 0 */ + struct t_gui_history *text_search_ptr_history; /* ptr to history found */ + char *text_search_input; /* input saved before text search */ /* highlight settings for buffer */ char *highlight_words; /* list of words to highlight */ diff --git a/src/gui/gui-history.c b/src/gui/gui-history.c index ba4c1022f..399973849 100644 --- a/src/gui/gui-history.c +++ b/src/gui/gui-history.c @@ -39,6 +39,7 @@ #include "../plugins/plugin.h" #include "gui-history.h" #include "gui-buffer.h" +#include "gui-input.h" struct t_gui_history *gui_history = NULL; @@ -48,50 +49,103 @@ int num_gui_history = 0; /* + * Removes oldest history entry in a buffer. + */ + +void +gui_history_buffer_remove_oldest (struct t_gui_buffer *buffer) +{ + struct t_gui_history *ptr_history; + + if (buffer->text_search_ptr_history == buffer->last_history) + { + buffer->text_search_ptr_history = NULL; + buffer->text_search_found = 0; + gui_input_search_signal (buffer); + } + + ptr_history = buffer->last_history->prev_history; + if (buffer->ptr_history == buffer->last_history) + buffer->ptr_history = ptr_history; + ((buffer->last_history)->prev_history)->next_history = NULL; + if (buffer->last_history->text) + free (buffer->last_history->text); + free (buffer->last_history); + buffer->last_history = ptr_history; + + buffer->num_history--; +} + +/* * Adds a text/command to buffer's history. */ void gui_history_buffer_add (struct t_gui_buffer *buffer, const char *string) { - struct t_gui_history *new_history, *ptr_history; + struct t_gui_history *new_history; if (!string) return; - if (!buffer->history - || (buffer->history - && (strcmp (buffer->history->text, string) != 0))) + if (buffer->history && buffer->history->text + && (strcmp (buffer->history->text, string) == 0)) + return; + + new_history = malloc (sizeof (*new_history)); + if (new_history) { - new_history = malloc (sizeof (*new_history)); - if (new_history) + new_history->text = strdup (string); + if (buffer->history) + buffer->history->prev_history = new_history; + else + buffer->last_history = new_history; + new_history->next_history = buffer->history; + new_history->prev_history = NULL; + buffer->history = new_history; + buffer->num_history++; + + /* remove one command if necessary */ + if ((CONFIG_INTEGER(config_history_max_commands) > 0) + && (buffer->num_history > CONFIG_INTEGER(config_history_max_commands))) { - new_history->text = strdup (string); - if (buffer->history) - buffer->history->prev_history = new_history; - else - buffer->last_history = new_history; - new_history->next_history = buffer->history; - new_history->prev_history = NULL; - buffer->history = new_history; - buffer->num_history++; - - /* remove one command if necessary */ - if ((CONFIG_INTEGER(config_history_max_commands) > 0) - && (buffer->num_history > CONFIG_INTEGER(config_history_max_commands))) - { - ptr_history = buffer->last_history->prev_history; - if (buffer->ptr_history == buffer->last_history) - buffer->ptr_history = ptr_history; - ((buffer->last_history)->prev_history)->next_history = NULL; - if (buffer->last_history->text) - free (buffer->last_history->text); - free (buffer->last_history); - buffer->last_history = ptr_history; - buffer->num_history--; - } + gui_history_buffer_remove_oldest (buffer); + } + } +} + +/* + * Removes oldest global history entry. + */ + +void +gui_history_global_remove_oldest () +{ + struct t_gui_buffer *ptr_buffer; + struct t_gui_history *ptr_history; + + /* ensure no buffer is using the last global history entry */ + for (ptr_buffer = gui_buffers; ptr_buffer; + ptr_buffer = ptr_buffer->next_buffer) + { + if (ptr_buffer->text_search_ptr_history == last_gui_history) + { + ptr_buffer->text_search_ptr_history = NULL; + ptr_buffer->text_search_found = 0; + gui_input_search_signal (ptr_buffer); } } + + ptr_history = last_gui_history->prev_history; + if (gui_history_ptr == last_gui_history) + gui_history_ptr = ptr_history; + (last_gui_history->prev_history)->next_history = NULL; + if (last_gui_history->text) + free (last_gui_history->text); + free (last_gui_history); + last_gui_history = ptr_history; + + num_gui_history--; } /* @@ -101,42 +155,32 @@ gui_history_buffer_add (struct t_gui_buffer *buffer, const char *string) void gui_history_global_add (const char *string) { - struct t_gui_history *new_history, *ptr_history; + struct t_gui_history *new_history; if (!string) return; - if (!gui_history - || (gui_history - && (strcmp (gui_history->text, string) != 0))) + if (gui_history && (strcmp (gui_history->text, string) == 0)) + return; + + new_history = malloc (sizeof (*new_history)); + if (new_history) { - new_history = malloc (sizeof (*new_history)); - if (new_history) + new_history->text = strdup (string); + if (gui_history) + gui_history->prev_history = new_history; + else + last_gui_history = new_history; + new_history->next_history = gui_history; + new_history->prev_history = NULL; + gui_history = new_history; + num_gui_history++; + + /* remove one command if necessary */ + if ((CONFIG_INTEGER(config_history_max_commands) > 0) + && (num_gui_history > CONFIG_INTEGER(config_history_max_commands))) { - new_history->text = strdup (string); - if (gui_history) - gui_history->prev_history = new_history; - else - last_gui_history = new_history; - new_history->next_history = gui_history; - new_history->prev_history = NULL; - gui_history = new_history; - num_gui_history++; - - /* remove one command if necessary */ - if ((CONFIG_INTEGER(config_history_max_commands) > 0) - && (num_gui_history > CONFIG_INTEGER(config_history_max_commands))) - { - ptr_history = last_gui_history->prev_history; - if (gui_history_ptr == last_gui_history) - gui_history_ptr = ptr_history; - (last_gui_history->prev_history)->next_history = NULL; - if (last_gui_history->text) - free (last_gui_history->text); - free (last_gui_history); - last_gui_history = ptr_history; - num_gui_history--; - } + gui_history_global_remove_oldest (); } } } @@ -169,6 +213,93 @@ gui_history_add (struct t_gui_buffer *buffer, const char *string) } /* + * Searches for text in a history entry. + * + * Returns: + * 1: text found in line + * 0: text not found in line + */ + +int +gui_history_search_text (struct t_gui_buffer *buffer, + struct t_gui_history *history) +{ + int rc; + + if (!history || !history->text + || !buffer->input_buffer || !buffer->input_buffer[0]) + { + return 0; + } + + rc = 0; + + if (buffer->text_search_regex) + { + if (buffer->text_search_regex_compiled + && (regexec (buffer->text_search_regex_compiled, + history->text, 0, NULL, 0) == 0)) + { + rc = 1; + } + } + else if ((buffer->text_search_exact + && (strstr (history->text, buffer->input_buffer))) + || (!buffer->text_search_exact + && (string_strcasestr (history->text, buffer->input_buffer)))) + { + rc = 1; + } + + return rc; +} + +/* + * Searches in history using string in buffer input. + * + * Returns: + * 1: an history was found + * 0: text not found + */ + +int +gui_history_search (struct t_gui_buffer *buffer, + struct t_gui_history *history) +{ + struct t_gui_history *ptr_history; + int direction; + + if (!buffer->input_buffer || !buffer->input_buffer[0]) + return 0; + + direction = (buffer->text_search_direction == GUI_BUFFER_SEARCH_DIR_BACKWARD) ? + 1 : -1; + + if (buffer->text_search_ptr_history) + { + ptr_history = (direction > 0) ? + buffer->text_search_ptr_history->next_history : + buffer->text_search_ptr_history->prev_history; + } + else + { + ptr_history = history; + } + + while (ptr_history) + { + if (gui_history_search_text (buffer, ptr_history)) + { + buffer->text_search_ptr_history = ptr_history; + return 1; + } + ptr_history = (direction > 0) ? + ptr_history->next_history : ptr_history->prev_history; + } + return 0; +} + +/* * Frees global history. */ diff --git a/src/gui/gui-history.h b/src/gui/gui-history.h index edbb1acd8..f0915268b 100644 --- a/src/gui/gui-history.h +++ b/src/gui/gui-history.h @@ -37,6 +37,8 @@ extern void gui_history_buffer_add (struct t_gui_buffer *buffer, const char *string); extern void gui_history_global_add (const char *string); extern void gui_history_add (struct t_gui_buffer *buffer, const char *string); +extern int gui_history_search (struct t_gui_buffer *buffer, + struct t_gui_history *history); extern void gui_history_global_free (); extern void gui_history_buffer_free (struct t_gui_buffer *buffer); extern struct t_hdata *gui_history_hdata_history_cb (const void *pointer, diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c index e4658b872..0eb3d5986 100644 --- a/src/gui/gui-input.c +++ b/src/gui/gui-input.c @@ -214,7 +214,6 @@ gui_input_search_signal (struct t_gui_buffer *buffer) { gui_window_bare_display_toggle (NULL); } - (void) hook_signal_send ("input_search", WEECHAT_HOOK_SIGNAL_POINTER, buffer); } @@ -498,7 +497,7 @@ gui_input_complete (struct t_gui_buffer *buffer) void gui_input_complete_next (struct t_gui_buffer *buffer) { - if (!buffer->input ||(buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) + if (!buffer->input || (buffer->text_search != GUI_BUFFER_SEARCH_DISABLED)) return; gui_buffer_undo_snap (buffer); @@ -522,7 +521,7 @@ gui_input_complete_next (struct t_gui_buffer *buffer) void gui_input_complete_previous (struct t_gui_buffer *buffer) { - if (!buffer->input || (buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) + if (!buffer->input || (buffer->text_search != GUI_BUFFER_SEARCH_DISABLED)) return; gui_buffer_undo_snap (buffer); @@ -549,9 +548,10 @@ gui_input_search_text_here (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) + if (window && (window->buffer->text_search == GUI_BUFFER_SEARCH_DISABLED)) { - gui_window_search_start (window, window->scroll->start_line); + gui_window_search_start (window, GUI_BUFFER_SEARCH_LINES, + window->scroll->start_line); gui_input_search_signal (buffer); } } @@ -566,9 +566,26 @@ gui_input_search_text (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) + if (window && (window->buffer->text_search == GUI_BUFFER_SEARCH_DISABLED)) { - gui_window_search_start (window, NULL); + gui_window_search_start (window, GUI_BUFFER_SEARCH_LINES, NULL); + gui_input_search_signal (buffer); + } +} + +/* + * Searches for text in buffer/global command line history. + */ + +void +gui_input_search_history (struct t_gui_buffer *buffer) +{ + struct t_gui_window *window; + + window = gui_window_search_with_buffer (buffer); + if (window && (window->buffer->text_search == GUI_BUFFER_SEARCH_DISABLED)) + { + gui_window_search_start (window, GUI_BUFFER_SEARCH_HISTORY, NULL); gui_input_search_signal (buffer); } } @@ -619,7 +636,7 @@ gui_input_search_switch_case (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) + if (window && (window->buffer->text_search != GUI_BUFFER_SEARCH_DISABLED)) { window->buffer->text_search_exact ^= 1; gui_window_search_restart (window); @@ -638,7 +655,7 @@ gui_input_search_switch_regex (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) + if (window && (window->buffer->text_search != GUI_BUFFER_SEARCH_DISABLED)) { window->buffer->text_search_regex ^= 1; gui_window_search_restart (window); @@ -656,20 +673,35 @@ gui_input_search_switch_where (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) - { - /* it's not possible to change that in a buffer not "formatted" */ - if (window->buffer->type != GUI_BUFFER_TYPE_FORMATTED) - return; + if (!window) + return; - if (window->buffer->text_search_where == GUI_TEXT_SEARCH_IN_MESSAGE) - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_PREFIX; - else if (window->buffer->text_search_where == GUI_TEXT_SEARCH_IN_PREFIX) - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_MESSAGE | GUI_TEXT_SEARCH_IN_PREFIX; - else - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_MESSAGE; - gui_window_search_restart (window); - gui_input_search_signal (buffer); + switch (window->buffer->text_search) + { + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + /* it's not possible to change that in a buffer not "formatted" */ + if (window->buffer->type != GUI_BUFFER_TYPE_FORMATTED) + return; + if (window->buffer->text_search_where == GUI_BUFFER_SEARCH_IN_MESSAGE) + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_PREFIX; + else if (window->buffer->text_search_where == GUI_BUFFER_SEARCH_IN_PREFIX) + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_MESSAGE | GUI_BUFFER_SEARCH_IN_PREFIX; + else + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_MESSAGE; + gui_window_search_restart (window); + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_SEARCH_HISTORY: + window->buffer->text_search_history = + (window->buffer->text_search_history == GUI_BUFFER_SEARCH_HISTORY_LOCAL) ? + GUI_BUFFER_SEARCH_HISTORY_GLOBAL : GUI_BUFFER_SEARCH_HISTORY_LOCAL; + gui_window_search_restart (window); + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } @@ -683,10 +715,24 @@ gui_input_search_previous (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) - { - window->buffer->text_search = GUI_TEXT_SEARCH_BACKWARD; - (void) gui_window_search_text (window); + if (!window) + return; + + switch (window->buffer->text_search) + { + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_BACKWARD; + (void) gui_window_search_text (window); + break; + case GUI_BUFFER_SEARCH_HISTORY: + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_BACKWARD; + if (gui_window_search_text (window)) + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } @@ -700,10 +746,24 @@ gui_input_search_next (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) - { - window->buffer->text_search = GUI_TEXT_SEARCH_FORWARD; - (void) gui_window_search_text (window); + if (!window) + return; + + switch (window->buffer->text_search) + { + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_FORWARD; + (void) gui_window_search_text (window); + break; + case GUI_BUFFER_SEARCH_HISTORY: + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_FORWARD; + if (gui_window_search_text (window)) + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } @@ -717,10 +777,20 @@ gui_input_search_stop_here (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) + if (!window) + return; + + switch (window->buffer->text_search) { - gui_window_search_stop_here (window); - gui_input_search_signal (buffer); + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + case GUI_BUFFER_SEARCH_HISTORY: + gui_window_search_stop (window, 1); + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } @@ -734,10 +804,20 @@ gui_input_search_stop (struct t_gui_buffer *buffer) struct t_gui_window *window; window = gui_window_search_with_buffer (buffer); - if (window && (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) - { - gui_window_search_stop (window); - gui_input_search_signal (buffer); + if (!window) + return; + + switch (window->buffer->text_search) + { + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + case GUI_BUFFER_SEARCH_HISTORY: + gui_window_search_stop (window, 0); + gui_input_search_signal (buffer); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } diff --git a/src/gui/gui-input.h b/src/gui/gui-input.h index b176ea424..9fa754122 100644 --- a/src/gui/gui-input.h +++ b/src/gui/gui-input.h @@ -34,6 +34,7 @@ extern void gui_input_paste_pending_signal (); extern void gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer, int save_undo, int stop_completion); +extern void gui_input_search_signal (struct t_gui_buffer *buffer); extern void gui_input_set_pos (struct t_gui_buffer *buffer, int pos); extern void gui_input_insert_string (struct t_gui_buffer *buffer, const char *string); @@ -44,6 +45,7 @@ extern void gui_input_complete_next (struct t_gui_buffer *buffer); extern void gui_input_complete_previous (struct t_gui_buffer *buffer); extern void gui_input_search_text_here (struct t_gui_buffer *buffer); extern void gui_input_search_text (struct t_gui_buffer *buffer); +extern void gui_input_search_history (struct t_gui_buffer *buffer); extern void gui_input_search_compile_regex (struct t_gui_buffer *buffer); extern void gui_input_search_switch_case (struct t_gui_buffer *buffer); extern void gui_input_search_switch_regex (struct t_gui_buffer *buffer); diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index 90da58642..cfcbff3ba 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -66,7 +66,7 @@ int gui_keys_count[GUI_KEY_NUM_CONTEXTS]; /* keys number */ int gui_default_keys_count[GUI_KEY_NUM_CONTEXTS]; /* default keys number */ char *gui_key_context_string[GUI_KEY_NUM_CONTEXTS] = -{ "default", "search", "cursor", "mouse" }; +{ "default", "search", "histsearch", "cursor", "mouse" }; char *gui_key_focus_string[GUI_KEY_NUM_FOCUS] = { "*", "chat", "bar", "item" }; @@ -173,9 +173,13 @@ gui_key_get_current_context () if (gui_cursor_mode) return GUI_KEY_CONTEXT_CURSOR; - if (gui_current_window - && (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)) - return GUI_KEY_CONTEXT_SEARCH; + if (gui_current_window) + { + if (gui_current_window->buffer->text_search == GUI_BUFFER_SEARCH_LINES) + return GUI_KEY_CONTEXT_SEARCH; + if (gui_current_window->buffer->text_search == GUI_BUFFER_SEARCH_HISTORY) + return GUI_KEY_CONTEXT_HISTSEARCH; + } return GUI_KEY_CONTEXT_DEFAULT; } @@ -2437,7 +2441,7 @@ gui_key_pressed (const char *key_str) /* look for key combo in key table for current buffer */ ptr_key = gui_key_search_part ( gui_current_window->buffer, - GUI_KEY_CONTEXT_DEFAULT, + context, (const char **)chunks1, chunks1_count, (const char **)chunks2, chunks2_count, &exact_match); @@ -2446,21 +2450,23 @@ gui_key_pressed (const char *key_str) { ptr_key = gui_key_search_part ( NULL, - GUI_KEY_CONTEXT_DEFAULT, + context, (const char **)chunks1, chunks1_count, (const char **)chunks2, chunks2_count, &exact_match); } break; case GUI_KEY_CONTEXT_SEARCH: + case GUI_KEY_CONTEXT_HISTSEARCH: ptr_key = gui_key_search_part ( NULL, - GUI_KEY_CONTEXT_SEARCH, + context, (const char **)chunks1, chunks1_count, (const char **)chunks2, chunks2_count, &exact_match); if (!ptr_key) { + /* fallback to default context */ ptr_key = gui_key_search_part ( NULL, GUI_KEY_CONTEXT_DEFAULT, @@ -2472,7 +2478,7 @@ gui_key_pressed (const char *key_str) case GUI_KEY_CONTEXT_CURSOR: ptr_key = gui_key_search_part ( NULL, - GUI_KEY_CONTEXT_CURSOR, + context, (const char **)chunks1, chunks1_count, (const char **)chunks2, chunks2_count, &exact_match); diff --git a/src/gui/gui-key.h b/src/gui/gui-key.h index cbc600c2f..5d0170f44 100644 --- a/src/gui/gui-key.h +++ b/src/gui/gui-key.h @@ -34,6 +34,7 @@ enum t_gui_key_context { GUI_KEY_CONTEXT_DEFAULT = 0, GUI_KEY_CONTEXT_SEARCH, + GUI_KEY_CONTEXT_HISTSEARCH, GUI_KEY_CONTEXT_CURSOR, GUI_KEY_CONTEXT_MOUSE, /* number of key contexts */ diff --git a/src/gui/gui-line.c b/src/gui/gui-line.c index efef30959..adfee35b5 100644 --- a/src/gui/gui-line.c +++ b/src/gui/gui-line.c @@ -593,7 +593,7 @@ gui_line_search_text (struct t_gui_buffer *buffer, struct t_gui_line *line) rc = 0; - if ((buffer->text_search_where & GUI_TEXT_SEARCH_IN_PREFIX) + if ((buffer->text_search_where & GUI_BUFFER_SEARCH_IN_PREFIX) && line->data->prefix) { prefix = gui_color_decode (line->data->prefix, NULL); @@ -621,7 +621,7 @@ gui_line_search_text (struct t_gui_buffer *buffer, struct t_gui_line *line) } } - if (!rc && (buffer->text_search_where & GUI_TEXT_SEARCH_IN_MESSAGE)) + if (!rc && (buffer->text_search_where & GUI_BUFFER_SEARCH_IN_MESSAGE)) { if (gui_chat_display_tags) { diff --git a/src/gui/gui-window.c b/src/gui/gui-window.c index 76a585f1d..ae9a48713 100644 --- a/src/gui/gui-window.c +++ b/src/gui/gui-window.c @@ -50,6 +50,7 @@ #include "gui-color.h" #include "gui-filter.h" #include "gui-input.h" +#include "gui-history.h" #include "gui-hotlist.h" #include "gui-layout.h" #include "gui-line.h" @@ -1501,8 +1502,7 @@ gui_window_scroll_previous_highlight (struct t_gui_window *window) if (!window) return; - if ((window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) - && (window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) + if (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) { if (window->buffer->lines->first_line) { @@ -1539,8 +1539,7 @@ gui_window_scroll_next_highlight (struct t_gui_window *window) if (!window) return; - if ((window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) - && (window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) + if (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) { if (window->buffer->lines->first_line) { @@ -1575,38 +1574,35 @@ gui_window_scroll_unread (struct t_gui_window *window) if (!window) return; - if (window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) + if (CONFIG_STRING(config_look_read_marker) && + CONFIG_STRING(config_look_read_marker)[0] && + (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) && + (window->buffer->lines->first_line_not_read || + (window->buffer->lines->last_read_line && + window->buffer->lines->last_read_line != window->buffer->lines->last_line))) { - if (CONFIG_STRING(config_look_read_marker) && - CONFIG_STRING(config_look_read_marker)[0] && - (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) && - (window->buffer->lines->first_line_not_read || - (window->buffer->lines->last_read_line && - window->buffer->lines->last_read_line != window->buffer->lines->last_line))) + if (window->buffer->lines->first_line_not_read) + window->scroll->start_line = window->buffer->lines->first_line; + else + window->scroll->start_line = window->buffer->lines->last_read_line->next_line; + if (window->scroll->start_line) { - if (window->buffer->lines->first_line_not_read) - window->scroll->start_line = window->buffer->lines->first_line; - else - window->scroll->start_line = window->buffer->lines->last_read_line->next_line; - if (window->scroll->start_line) - { - if (!gui_line_is_displayed (window->scroll->start_line)) - window->scroll->start_line = gui_line_get_next_displayed (window->scroll->start_line); - } - window->scroll->start_line_pos = 0; - window->scroll->first_line_displayed = - (window->scroll->start_line == gui_line_get_first_displayed (window->buffer)); - gui_buffer_ask_chat_refresh (window->buffer, 2); + if (!gui_line_is_displayed (window->scroll->start_line)) + window->scroll->start_line = gui_line_get_next_displayed (window->scroll->start_line); } + window->scroll->start_line_pos = 0; + window->scroll->first_line_displayed = + (window->scroll->start_line == gui_line_get_first_displayed (window->buffer)); + gui_buffer_ask_chat_refresh (window->buffer, 2); } } /* - * Searches for text in a buffer. + * Searches for text in buffer lines or commands history. * * Returns: - * 1: line has been found with text - * 0: no line found with text + * 1: successful search + * 0: no results found */ int @@ -1617,51 +1613,66 @@ gui_window_search_text (struct t_gui_window *window) if (!window) return 0; - if (window->buffer->text_search == GUI_TEXT_SEARCH_BACKWARD) + switch (window->buffer->text_search) { - if (window->buffer->lines->first_line - && window->buffer->input_buffer && window->buffer->input_buffer[0]) - { - ptr_line = (window->scroll->start_line) ? - gui_line_get_prev_displayed (window->scroll->start_line) : - gui_line_get_last_displayed (window->buffer); - while (ptr_line) + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + if (window->buffer->text_search_direction == GUI_BUFFER_SEARCH_DIR_BACKWARD) { - if (gui_line_search_text (window->buffer, ptr_line)) + if (window->buffer->lines->first_line + && window->buffer->input_buffer && window->buffer->input_buffer[0]) { - window->scroll->start_line = ptr_line; - window->scroll->start_line_pos = 0; - window->scroll->first_line_displayed = - (window->scroll->start_line == gui_line_get_first_displayed (window->buffer)); - gui_buffer_ask_chat_refresh (window->buffer, 2); - return 1; + ptr_line = (window->scroll->start_line) ? + gui_line_get_prev_displayed (window->scroll->start_line) : + gui_line_get_last_displayed (window->buffer); + while (ptr_line) + { + if (gui_line_search_text (window->buffer, ptr_line)) + { + window->scroll->start_line = ptr_line; + window->scroll->start_line_pos = 0; + window->scroll->first_line_displayed = + (window->scroll->start_line == gui_line_get_first_displayed (window->buffer)); + gui_buffer_ask_chat_refresh (window->buffer, 2); + return 1; + } + ptr_line = gui_line_get_prev_displayed (ptr_line); + } } - ptr_line = gui_line_get_prev_displayed (ptr_line); } - } - } - else if (window->buffer->text_search == GUI_TEXT_SEARCH_FORWARD) - { - if (window->buffer->lines->first_line - && window->buffer->input_buffer && window->buffer->input_buffer[0]) - { - ptr_line = (window->scroll->start_line) ? - gui_line_get_next_displayed (window->scroll->start_line) : - gui_line_get_first_displayed (window->buffer); - while (ptr_line) + else if (window->buffer->text_search_direction == GUI_BUFFER_SEARCH_DIR_FORWARD) { - if (gui_line_search_text (window->buffer, ptr_line)) + if (window->buffer->lines->first_line + && window->buffer->input_buffer && window->buffer->input_buffer[0]) { - window->scroll->start_line = ptr_line; - window->scroll->start_line_pos = 0; - window->scroll->first_line_displayed = - (window->scroll->start_line == window->buffer->lines->first_line); - gui_buffer_ask_chat_refresh (window->buffer, 2); - return 1; + ptr_line = (window->scroll->start_line) ? + gui_line_get_next_displayed (window->scroll->start_line) : + gui_line_get_first_displayed (window->buffer); + while (ptr_line) + { + if (gui_line_search_text (window->buffer, ptr_line)) + { + window->scroll->start_line = ptr_line; + window->scroll->start_line_pos = 0; + window->scroll->first_line_displayed = + (window->scroll->start_line == window->buffer->lines->first_line); + gui_buffer_ask_chat_refresh (window->buffer, 2); + return 1; + } + ptr_line = gui_line_get_next_displayed (ptr_line); + } } - ptr_line = gui_line_get_next_displayed (ptr_line); } - } + break; + case GUI_BUFFER_SEARCH_HISTORY: + return gui_history_search ( + window->buffer, + (window->buffer->text_search_history == GUI_BUFFER_SEARCH_HISTORY_LOCAL) ? + window->buffer->history : gui_history); + break; + case GUI_BUFFER_NUM_SEARCH: + break; } return 0; } @@ -1672,45 +1683,75 @@ gui_window_search_text (struct t_gui_window *window) */ void -gui_window_search_start (struct t_gui_window *window, +gui_window_search_start (struct t_gui_window *window, int search, struct t_gui_line *text_search_start_line) { if (!window) return; - window->scroll->text_search_start_line = text_search_start_line; - window->buffer->text_search = - (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) ? - GUI_TEXT_SEARCH_BACKWARD : GUI_TEXT_SEARCH_FORWARD; + window->buffer->text_search = search; - if ((window->buffer->text_search_where == 0) - || CONFIG_BOOLEAN(config_look_buffer_search_force_default)) + switch (window->buffer->text_search) { - /* set default search values */ - window->buffer->text_search_exact = CONFIG_BOOLEAN(config_look_buffer_search_case_sensitive); - window->buffer->text_search_regex = CONFIG_BOOLEAN(config_look_buffer_search_regex); - if (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) - { - switch (CONFIG_ENUM(config_look_buffer_search_where)) + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + window->buffer->text_search_direction = (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) ? + GUI_BUFFER_SEARCH_DIR_BACKWARD : GUI_BUFFER_SEARCH_DIR_FORWARD; + window->scroll->text_search_start_line = text_search_start_line; + if ((window->buffer->text_search_where == 0) + || CONFIG_BOOLEAN(config_look_buffer_search_force_default)) { - case CONFIG_LOOK_BUFFER_SEARCH_PREFIX: - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_PREFIX; - break; - case CONFIG_LOOK_BUFFER_SEARCH_MESSAGE: - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_MESSAGE; - break; - case CONFIG_LOOK_BUFFER_SEARCH_PREFIX_MESSAGE: - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_PREFIX | GUI_TEXT_SEARCH_IN_MESSAGE; - break; - default: - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_MESSAGE; - break; - } + if (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) + { + switch (CONFIG_ENUM(config_look_buffer_search_where)) + { + case CONFIG_LOOK_BUFFER_SEARCH_PREFIX: + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_PREFIX; + break; + case CONFIG_LOOK_BUFFER_SEARCH_MESSAGE: + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_MESSAGE; + break; + case CONFIG_LOOK_BUFFER_SEARCH_PREFIX_MESSAGE: + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_PREFIX + | GUI_BUFFER_SEARCH_IN_MESSAGE; + break; + default: + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_MESSAGE; + break; + } + } + else + { + window->buffer->text_search_where = GUI_BUFFER_SEARCH_IN_MESSAGE; + } + break; + case GUI_BUFFER_SEARCH_HISTORY: + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_BACKWARD; + if ((window->buffer->text_search_history == GUI_BUFFER_SEARCH_HISTORY_NONE) + || CONFIG_BOOLEAN(config_look_buffer_search_force_default)) + { + switch (CONFIG_ENUM(config_look_buffer_search_history)) + { + case CONFIG_LOOK_BUFFER_SEARCH_HISTORY_LOCAL: + window->buffer->text_search_history = GUI_BUFFER_SEARCH_HISTORY_LOCAL; + break; + case CONFIG_LOOK_BUFFER_SEARCH_HISTORY_GLOBAL: + window->buffer->text_search_history = GUI_BUFFER_SEARCH_HISTORY_GLOBAL; + break; + default: + window->buffer->text_search_history = GUI_BUFFER_SEARCH_HISTORY_LOCAL; + break; + } + } + break; + case GUI_BUFFER_NUM_SEARCH: + break; } - else - window->buffer->text_search_where = GUI_TEXT_SEARCH_IN_MESSAGE; } + window->buffer->text_search_exact = CONFIG_BOOLEAN(config_look_buffer_search_case_sensitive); + window->buffer->text_search_regex = CONFIG_BOOLEAN(config_look_buffer_search_regex); window->buffer->text_search_found = 0; gui_input_search_compile_regex (window->buffer); if (window->buffer->text_search_input) @@ -1734,39 +1775,80 @@ gui_window_search_restart (struct t_gui_window *window) if (!window) return; - window->scroll->start_line = window->scroll->text_search_start_line; - window->scroll->start_line_pos = 0; - window->buffer->text_search = - (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) ? - GUI_TEXT_SEARCH_BACKWARD : GUI_TEXT_SEARCH_FORWARD; - window->buffer->text_search_found = 0; - gui_input_search_compile_regex (window->buffer); - if (gui_window_search_text (window)) - window->buffer->text_search_found = 1; - else + switch (window->buffer->text_search) { - if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert) - && window->buffer->input_buffer && window->buffer->input_buffer[0]) - { - fprintf (stderr, "\a"); - fflush (stderr); - } - gui_buffer_ask_chat_refresh (window->buffer, 2); + case GUI_BUFFER_SEARCH_DISABLED: + break; + case GUI_BUFFER_SEARCH_LINES: + window->scroll->start_line = window->scroll->text_search_start_line; + window->scroll->start_line_pos = 0; + window->buffer->text_search_direction = + (window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) ? + GUI_BUFFER_SEARCH_DIR_BACKWARD : GUI_BUFFER_SEARCH_DIR_FORWARD; + gui_input_search_compile_regex (window->buffer); + window->buffer->text_search_found = 0; + if (gui_window_search_text (window)) + { + window->buffer->text_search_found = 1; + } + else + { + if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert) + && window->buffer->input_buffer && window->buffer->input_buffer[0]) + { + fprintf (stderr, "\a"); + fflush (stderr); + } + gui_buffer_ask_chat_refresh (window->buffer, 2); + } + break; + case GUI_BUFFER_SEARCH_HISTORY: + gui_input_search_compile_regex (window->buffer); + window->buffer->text_search_found = 0; + window->buffer->text_search_ptr_history = NULL; + if (gui_window_search_text (window)) + { + window->buffer->text_search_found = 1; + } + else + { + if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert) + && window->buffer->input_buffer && window->buffer->input_buffer[0]) + { + fprintf (stderr, "\a"); + fflush (stderr); + } + } + break; + case GUI_BUFFER_NUM_SEARCH: + break; } } /* - * Ends search mode in a buffer (helper function). + * Stops search in a buffer, at current position if stop_here == 1 or reset + * scroll to the initial value if stop_here == 0. */ void -gui_window_search_end (struct t_gui_window *window) +gui_window_search_stop (struct t_gui_window *window, int stop_here) { + const char *ptr_new_input; + int search; + if (!window) return; - window->buffer->text_search = GUI_TEXT_SEARCH_DISABLED; - window->buffer->text_search = 0; + search = window->buffer->text_search; + + ptr_new_input = (stop_here + && (window->buffer->text_search == GUI_BUFFER_SEARCH_HISTORY) + && window->buffer->text_search_ptr_history + && window->buffer->text_search_ptr_history->text) ? + window->buffer->text_search_ptr_history->text : window->buffer->text_search_input; + + window->buffer->text_search = GUI_BUFFER_SEARCH_DISABLED; + window->buffer->text_search_direction = GUI_BUFFER_SEARCH_DIR_BACKWARD; if (window->buffer->text_search_regex_compiled) { regfree (window->buffer->text_search_regex_compiled); @@ -1774,49 +1856,31 @@ gui_window_search_end (struct t_gui_window *window) window->buffer->text_search_regex_compiled = NULL; } gui_input_delete_line (window->buffer); - if (window->buffer->text_search_input) + if (ptr_new_input) { - gui_input_insert_string (window->buffer, - window->buffer->text_search_input); + gui_input_insert_string (window->buffer, ptr_new_input); gui_input_text_changed_modifier_and_signal (window->buffer, 0, /* save undo */ 1); /* stop completion */ + } + if (window->buffer->text_search_input) + { free (window->buffer->text_search_input); window->buffer->text_search_input = NULL; } -} - -/* - * Stops search in a buffer at current position. - */ - -void -gui_window_search_stop_here (struct t_gui_window *window) -{ - if (!window) - return; + window->buffer->text_search_ptr_history = NULL; - gui_window_search_end (window); - window->scroll->text_search_start_line = NULL; - gui_buffer_ask_chat_refresh (window->buffer, 2); -} - -/* - * Stops search in a buffer. - */ - -void -gui_window_search_stop (struct t_gui_window *window) -{ - if (!window) - return; - - gui_window_search_end (window); - window->scroll->start_line = window->scroll->text_search_start_line; - window->scroll->start_line_pos = 0; - window->scroll->text_search_start_line = NULL; - gui_hotlist_remove_buffer (window->buffer, 0); - gui_buffer_ask_chat_refresh (window->buffer, 2); + if (search == GUI_BUFFER_SEARCH_LINES) + { + window->scroll->text_search_start_line = NULL; + if (!stop_here) + { + window->scroll->start_line = window->scroll->text_search_start_line; + window->scroll->start_line_pos = 0; + gui_hotlist_remove_buffer (window->buffer, 0); + } + gui_buffer_ask_chat_refresh (window->buffer, 2); + } } /* diff --git a/src/gui/gui-window.h b/src/gui/gui-window.h index 6e1b2eb76..2d697f406 100644 --- a/src/gui/gui-window.h +++ b/src/gui/gui-window.h @@ -188,10 +188,10 @@ extern void gui_window_scroll_previous_highlight (struct t_gui_window *window); extern void gui_window_scroll_next_highlight (struct t_gui_window *window); extern void gui_window_scroll_unread (struct t_gui_window *window); extern void gui_window_search_start (struct t_gui_window *window, + int search, struct t_gui_line *text_search_start_line); extern void gui_window_search_restart (struct t_gui_window *window); -extern void gui_window_search_stop_here (struct t_gui_window *window); -extern void gui_window_search_stop (struct t_gui_window *window); +extern void gui_window_search_stop (struct t_gui_window *window, int stop_here); extern int gui_window_search_text (struct t_gui_window *window); extern void gui_window_zoom (struct t_gui_window *window); extern struct t_hdata *gui_window_hdata_window_cb (const void *pointer, |