From 313b40235ac5f4a5bef4e27a9d2b8331e6b0c8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Tue, 14 Mar 2023 20:49:32 +0100 Subject: [PATCH] core: fix search of commands with raw code and alias matching When raw code and alias for a key are both matching, the raw code must always have higher priority. This commit fixes this behavior and gives priority to raw code. --- src/gui/gui-key.c | 33 ++++++++---- tests/unit/gui/test-gui-key.cpp | 91 ++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 12 deletions(-) diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index 59ca20ec0..0e974bdbd 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -1608,13 +1608,16 @@ gui_key_search_part (struct t_gui_buffer *buffer, int context, const char **chunks2, int chunks2_count, int *exact_match) { - struct t_gui_key *ptr_key; - int rc; + struct t_gui_key *ptr_key, *key1_found, *key2_found; + int rc, rc1, rc2; if ((!chunks1 && !chunks2) || !exact_match) return NULL; - *exact_match = 0; + key1_found = NULL; + key2_found = NULL; + rc1 = 0; + rc2 = 0; for (ptr_key = (buffer) ? buffer->keys : gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key) @@ -1629,11 +1632,13 @@ gui_key_search_part (struct t_gui_buffer *buffer, int context, chunks1_count, (const char **)ptr_key->chunks, ptr_key->chunks_count); - if (rc > 0) + if (rc > rc1) { + rc1 = rc; + key1_found = ptr_key; + /* exit immediately if raw key is an exact match */ if (rc == 2) - *exact_match = 1; - break; + break; } } if (chunks2) @@ -1642,17 +1647,23 @@ gui_key_search_part (struct t_gui_buffer *buffer, int context, chunks2_count, (const char **)ptr_key->chunks, ptr_key->chunks_count); - if (rc > 0) + if (rc > rc2) { - if (rc == 2) - *exact_match = 1; - break; + rc2 = rc; + key2_found = ptr_key; } } } } - return ptr_key; + if (key1_found) + { + *exact_match = (rc1 == 2) ? 1 : 0; + return key1_found; + } + + *exact_match = (rc2 == 2) ? 1 : 0; + return key2_found; } /* diff --git a/tests/unit/gui/test-gui-key.cpp b/tests/unit/gui/test-gui-key.cpp index 447a8e163..800f7c4f0 100644 --- a/tests/unit/gui/test-gui-key.cpp +++ b/tests/unit/gui/test-gui-key.cpp @@ -1304,6 +1304,7 @@ TEST(GuiKey, SearchPart) char **chunks1, **chunks2; int chunks1_count, chunks2_count, exact_match; + /* keys meta-a and meta-w */ chunks1 = string_split ("meta-a", ",", NULL, 0, 0, &chunks1_count); chunks2 = string_split ("meta-w", ",", NULL, 0, 0, &chunks2_count); @@ -1340,7 +1341,8 @@ TEST(GuiKey, SearchPart) STRCMP_EQUAL("meta-w,meta-b", ptr_key->key); LONGS_EQUAL(0, exact_match); - new_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, "meta-w", "/mute", 1); + new_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, + "meta-w", "/print meta-w", 1); exact_match = -1; ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, @@ -1349,6 +1351,7 @@ TEST(GuiKey, SearchPart) &exact_match); CHECK(ptr_key); STRCMP_EQUAL("meta-w", ptr_key->key); + STRCMP_EQUAL("/print meta-w", ptr_key->command); LONGS_EQUAL(1, exact_match); gui_key_free (GUI_KEY_CONTEXT_DEFAULT, @@ -1357,6 +1360,92 @@ TEST(GuiKey, SearchPart) &gui_keys_count[GUI_KEY_CONTEXT_DEFAULT], new_key, 1); + + string_free_split (chunks1); + string_free_split (chunks2); + + /* keys ctrl-h and backspace */ + chunks1 = string_split ("ctrl-h", ",", NULL, 0, 0, &chunks1_count); + chunks2 = string_split ("backspace", ",", NULL, 0, 0, &chunks2_count); + + exact_match = -1; + ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + CHECK(ptr_key); + STRCMP_EQUAL("backspace", ptr_key->key); + STRCMP_EQUAL("/input delete_previous_char", ptr_key->command); + LONGS_EQUAL(1, exact_match); + + new_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, + "ctrl-h", "/print ctrl-h", 1); + + exact_match = -1; + ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + CHECK(ptr_key); + STRCMP_EQUAL("ctrl-h", ptr_key->key); + STRCMP_EQUAL("/print ctrl-h", ptr_key->command); + LONGS_EQUAL(1, exact_match); + + gui_key_free (GUI_KEY_CONTEXT_DEFAULT, + &gui_keys[GUI_KEY_CONTEXT_DEFAULT], + &last_gui_key[GUI_KEY_CONTEXT_DEFAULT], + &gui_keys_count[GUI_KEY_CONTEXT_DEFAULT], + new_key, + 1); + + new_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, + "ctrl-h,j", "/print ctrl-h,j", 1); + + exact_match = -1; + ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + CHECK(ptr_key); + STRCMP_EQUAL("ctrl-h,j", ptr_key->key); + STRCMP_EQUAL("/print ctrl-h,j", ptr_key->command); + LONGS_EQUAL(0, exact_match); + + string_free_split (chunks1); + chunks1 = string_split ("ctrl-h,j", ",", NULL, 0, 0, &chunks1_count); + + exact_match = -1; + ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + CHECK(ptr_key); + STRCMP_EQUAL("ctrl-h,j", ptr_key->key); + STRCMP_EQUAL("/print ctrl-h,j", ptr_key->command); + LONGS_EQUAL(1, exact_match); + + string_free_split (chunks1); + chunks1 = string_split ("ctrl-q,j", ",", NULL, 0, 0, &chunks1_count); + + exact_match = -1; + ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + CHECK(ptr_key); + STRCMP_EQUAL("backspace", ptr_key->key); + STRCMP_EQUAL("/input delete_previous_char", ptr_key->command); + LONGS_EQUAL(1, exact_match); + + gui_key_free (GUI_KEY_CONTEXT_DEFAULT, + &gui_keys[GUI_KEY_CONTEXT_DEFAULT], + &last_gui_key[GUI_KEY_CONTEXT_DEFAULT], + &gui_keys_count[GUI_KEY_CONTEXT_DEFAULT], + new_key, + 1); + + string_free_split (chunks1); + string_free_split (chunks2); } /*