diff --git a/ChangeLog.adoc b/ChangeLog.adoc index af0874183..789f8d2da 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -13,6 +13,10 @@ For a list of important changes that require manual actions, please look at rele [[v4.3.0]] == Version 4.3.0 (under dev) +New features:: + + * core: allow case insensitive search of partial buffer name with `(?i)name` in command `/buffer` + Bug fixes:: * irc: fix random date displayed when a received message contains tags but no "time" (issue #2064) diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index dfdb46f63..3da3088b5 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -2785,6 +2785,9 @@ gui_buffer_search_main () /* * Searches for a buffer by full name (example: "irc.libera.#weechat"). + * + * If full_name starts with "(?i)", the search starts after this string + * and the search is case insensitive. */ struct t_gui_buffer * @@ -2793,6 +2796,9 @@ gui_buffer_search_by_full_name (const char *full_name) struct t_gui_buffer *ptr_buffer; int case_sensitive; + if (!full_name) + return NULL; + case_sensitive = 1; if (strncmp (full_name, "(?i)", 4) == 0) { @@ -2825,7 +2831,7 @@ struct t_gui_buffer * gui_buffer_search_by_name (const char *plugin, const char *name) { struct t_gui_buffer *ptr_buffer; - int plugin_match, case_sensitive; + int plugin_match, plugin_case_sensitive, name_case_sensitive; if (!name || !name[0]) return gui_current_window->buffer; @@ -2833,13 +2839,23 @@ gui_buffer_search_by_name (const char *plugin, const char *name) if (plugin && (strcmp (plugin, "==") == 0)) return gui_buffer_search_by_full_name (name); - case_sensitive = 1; + plugin_case_sensitive = 1; + name_case_sensitive = 1; + + if (plugin && (strncmp (plugin, "(?i)", 4) == 0)) + { + plugin_case_sensitive = 0; + plugin += 4; + } if (strncmp (name, "(?i)", 4) == 0) { - case_sensitive = 0; + name_case_sensitive = 0; name += 4; } + if (!name[0]) + return gui_current_window->buffer; + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) { @@ -2848,14 +2864,19 @@ gui_buffer_search_by_name (const char *plugin, const char *name) plugin_match = 1; if (plugin && plugin[0]) { - if (strcmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0) + if ((plugin_case_sensitive + && (strcmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0)) + || (!plugin_case_sensitive + && (string_strcasecmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0))) + { plugin_match = 0; + } } if (plugin_match - && ((case_sensitive - && strcmp (ptr_buffer->name, name) == 0) - || (!case_sensitive - && string_strcasecmp (ptr_buffer->name, name) == 0))) + && ((name_case_sensitive + && (strcmp (ptr_buffer->name, name) == 0)) + || (!name_case_sensitive + && (string_strcasecmp (ptr_buffer->name, name) == 0)))) { return ptr_buffer; } @@ -2868,18 +2889,38 @@ gui_buffer_search_by_name (const char *plugin, const char *name) /* * Searches for a buffer by plugin and partial name. + * + * If plugin or name starts with "(?i)", the search starts after this string + * and the search is case insensitive. */ struct t_gui_buffer * gui_buffer_search_by_partial_name (const char *plugin, const char *name) { struct t_gui_buffer *ptr_start_buffer, *ptr_buffer, *buffer_partial_match[3]; - int plugin_match, length_name; + int plugin_case_sensitive, name_case_sensitive, plugin_match, length_name; const char *pos; if (!name || !name[0]) return gui_current_window->buffer; + plugin_case_sensitive = 1; + name_case_sensitive = 1; + + if (plugin && (strncmp (plugin, "(?i)", 4) == 0)) + { + plugin_case_sensitive = 0; + plugin += 4; + } + if (strncmp (name, "(?i)", 4) == 0) + { + name_case_sensitive = 0; + name += 4; + } + + if (!name[0]) + return gui_current_window->buffer; + /* 0: matches beginning of buffer name, 1: in the middle, 2: the end */ buffer_partial_match[0] = NULL; buffer_partial_match[1] = NULL; @@ -2899,12 +2940,20 @@ gui_buffer_search_by_partial_name (const char *plugin, const char *name) plugin_match = 1; if (plugin && plugin[0]) { - if (strcmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0) + if ((plugin_case_sensitive + && (strcmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0)) + || (!plugin_case_sensitive + && (string_strcasecmp (plugin, gui_buffer_get_plugin_name (ptr_buffer)) != 0))) + { plugin_match = 0; + } } if (plugin_match) { - pos = strstr (ptr_buffer->name, name); + if (name_case_sensitive) + pos = strstr (ptr_buffer->name, name); + else + pos = string_strcasestr (ptr_buffer->name, name); if (pos) { if (pos == ptr_buffer->name) @@ -2914,7 +2963,7 @@ gui_buffer_search_by_partial_name (const char *plugin, const char *name) /* matches full name, return it immediately */ return ptr_buffer; } - /* matches beginning of name */ + /* matches beginning of buffer name */ if (!buffer_partial_match[0]) buffer_partial_match[0] = ptr_buffer; } diff --git a/tests/unit/gui/test-gui-buffer.cpp b/tests/unit/gui/test-gui-buffer.cpp index f8a6dcf3c..66a219c66 100644 --- a/tests/unit/gui/test-gui-buffer.cpp +++ b/tests/unit/gui/test-gui-buffer.cpp @@ -1256,7 +1256,16 @@ TEST(GuiBuffer, AddValueNumDisplayed) TEST(GuiBuffer, IsMain) { - /* TODO: write tests */ + LONGS_EQUAL(0, gui_buffer_is_main ("", "")); + LONGS_EQUAL(0, gui_buffer_is_main (NULL, NULL)); + LONGS_EQUAL(0, gui_buffer_is_main ("core", NULL)); + LONGS_EQUAL(0, gui_buffer_is_main ("core", "")); + LONGS_EQUAL(0, gui_buffer_is_main (NULL, "weechat")); + LONGS_EQUAL(0, gui_buffer_is_main ("", "weechat")); + LONGS_EQUAL(0, gui_buffer_is_main ("test", "weechat")); + LONGS_EQUAL(0, gui_buffer_is_main ("core", "test")); + + LONGS_EQUAL(1, gui_buffer_is_main ("core", "weechat")); } /* @@ -1266,7 +1275,24 @@ TEST(GuiBuffer, IsMain) TEST(GuiBuffer, SearchMain) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_main ()); + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_main ()); + + gui_buffer_move_to_number (gui_buffers, 2); + POINTERS_EQUAL(gui_buffers->next_buffer, gui_buffer_search_main ()); + + gui_buffer_move_to_number (gui_buffers, 2); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_main ()); + + gui_buffer_close (buffer); } /* @@ -1276,7 +1302,28 @@ TEST(GuiBuffer, SearchMain) TEST(GuiBuffer, SearchByFullName) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name (NULL)); + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name ("")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name ("xxx")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name ("weechat")); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_full_name ("core.weechat")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_full_name ("core." TEST_BUFFER_NAME)); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name ("CORE.weechat")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_full_name ("(?i)CORE.weechat")); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_full_name ("CORE." TEST_BUFFER_NAME)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_full_name ("(?i)CORE." TEST_BUFFER_NAME)); + + gui_buffer_close (buffer); } /* @@ -1286,7 +1333,41 @@ TEST(GuiBuffer, SearchByFullName) TEST(GuiBuffer, SearchByName) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name (NULL, NULL)); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name (NULL, "")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("", NULL)); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("", "")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("==", NULL)); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("==", "")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_name ("==", "(?i)")); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_name ("==", "xxx")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_name ("==", "weechat")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("==", "core.weechat")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_name ("==", "core." TEST_BUFFER_NAME)); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("", "")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("", "(?i)")); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("core", "weechat")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_name ("core", TEST_BUFFER_NAME)); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_name ("CORE", "WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("(?i)CORE", "weechat")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("core", "(?i)WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_name ("(?i)CORE", "(?i)WEECHAT")); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_name ("CORE", TEST_BUFFER_NAME)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_name ("(?i)CORE", TEST_BUFFER_NAME)); + + gui_buffer_close (buffer); } /* @@ -1296,7 +1377,37 @@ TEST(GuiBuffer, SearchByName) TEST(GuiBuffer, SearchByPartialName) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name (NULL, NULL)); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name (NULL, "")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("", NULL)); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("", "")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("", "(?i)")); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("core", "weechat")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_partial_name ("core", TEST_BUFFER_NAME)); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_partial_name ("CORE", "WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("(?i)CORE", "weechat")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("core", "(?i)WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("(?i)CORE", "(?i)WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("(?i)CORE", "(?i)WEE")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("(?i)CORE", "(?i)CH")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("(?i)CORE", "(?i)CHAT")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_partial_name ("(?i)CORE", "(?i)S")); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_partial_name ("CORE", TEST_BUFFER_NAME)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_partial_name ("(?i)CORE", TEST_BUFFER_NAME)); + + gui_buffer_close (buffer); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_partial_name ("core", "weechat")); } /* @@ -1306,7 +1417,21 @@ TEST(GuiBuffer, SearchByPartialName) TEST(GuiBuffer, SearchByNumber) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_number (-1)); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number (0)); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number (3)); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_number (1)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_number (2)); + + gui_buffer_close (buffer); } /* @@ -1316,7 +1441,34 @@ TEST(GuiBuffer, SearchByNumber) TEST(GuiBuffer, SearchByNumberOrName) { - /* TODO: write tests */ + struct t_gui_buffer *buffer; + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name (NULL)); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("xxx")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("-1")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("0")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("3")); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_number_or_name ("1")); + POINTERS_EQUAL(buffer, gui_buffer_search_by_number_or_name ("2")); + + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_number_or_name ("weechat")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_number_or_name ("core.weechat")); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("CORE.WEECHAT")); + POINTERS_EQUAL(gui_buffers, gui_buffer_search_by_number_or_name ("(?i)CORE.WEECHAT")); + + POINTERS_EQUAL(buffer, gui_buffer_search_by_number_or_name (TEST_BUFFER_NAME)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_number_or_name ("core." TEST_BUFFER_NAME)); + POINTERS_EQUAL(NULL, gui_buffer_search_by_number_or_name ("CORE." TEST_BUFFER_NAME)); + POINTERS_EQUAL(buffer, gui_buffer_search_by_number_or_name ("(?i)CORE." TEST_BUFFER_NAME)); + + gui_buffer_close (buffer); } /*