From f111c32ff9dc63f4db08a27089b666e8fdce3eaf Mon Sep 17 00:00:00 2001 From: Tomasz N Date: Wed, 20 Nov 2024 01:06:36 +0100 Subject: fix(messages): no message kind for search pattern #31272 --- src/nvim/search.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index debc5697d1..159ab35f6f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1203,6 +1203,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, size_t patlen // Compute msg_row early. msg_start(); + msg_ext_set_kind("search_cmd"); // Get the offset, so we know how long it is. if (!cmd_silent -- cgit From 8516c2dc1f301c439695629fff771227dbe00d30 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sat, 23 Nov 2024 14:22:06 +0600 Subject: refactor(options): autogenerate valid values and flag enums for options (#31089) Problem: Option metadata like list of valid values for an option and option flags are not listed in the `options.lua` file and are instead manually defined in C, which means option metadata is split between several places. Solution: Put metadata such as list of valid values for an option and option flags in `options.lua`, and autogenerate the corresponding C variables and enums. Supersedes #28659 Co-authored-by: glepnir --- src/nvim/search.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index 159ab35f6f..f06b679b0d 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1423,7 +1423,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, size_t patlen cmdline_search_stat(dirc, &pos, &curwin->w_cursor, show_top_bot_msg, msgbuf, msgbuflen, (count != 1 || has_offset - || (!(fdo_flags & FDO_SEARCH) + || (!(fdo_flags & kOptFdoFlagSearch) && hasFolding(curwin, curwin->w_cursor.lnum, NULL, NULL))), SEARCH_STAT_DEF_MAX_COUNT, @@ -2350,7 +2350,7 @@ void showmatch(int c) } if ((lpos = findmatch(NULL, NUL)) == NULL) { // no match, so beep - vim_beep(BO_MATCH); + vim_beep(kOptBoFlagShowmatch); return; } @@ -2535,7 +2535,7 @@ int current_search(int count, bool forward) } } - if (fdo_flags & FDO_SEARCH && KeyTyped) { + if (fdo_flags & kOptFdoFlagSearch && KeyTyped) { foldOpenCursor(); } -- cgit From 2a7d0ed6145bf3f8b139c2694563f460f829813a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 23 Dec 2024 05:43:52 -0800 Subject: refactor: iwyu #31637 Result of `make iwyu` (after some "fixups"). --- src/nvim/search.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index f06b679b0d..faa14dfaf4 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -30,10 +30,10 @@ #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/garray.h" +#include "nvim/garray_defs.h" #include "nvim/getchar.h" #include "nvim/gettext_defs.h" #include "nvim/globals.h" -#include "nvim/highlight.h" #include "nvim/highlight_defs.h" #include "nvim/indent_c.h" #include "nvim/insexpand.h" @@ -41,7 +41,6 @@ #include "nvim/mark.h" #include "nvim/mark_defs.h" #include "nvim/mbyte.h" -#include "nvim/mbyte_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" -- cgit From 46c7faa00b165a1ad1b7cef8245df30d3dc3ef56 Mon Sep 17 00:00:00 2001 From: glepnir Date: Fri, 27 Dec 2024 14:23:06 +0800 Subject: vim-patch:9.1.0963: fuzzy-matching does not prefer full match (#31741) Problem: fuzzy-matching does not prefer full match (Maxim Kim) Solution: add additional score for a full match (glepnir) fixes: vim/vim#15654 closes: vim/vim#16300 https://github.com/vim/vim/commit/5a04999a7402201cf1b47ff10bc474dd1cdc24f4 --- src/nvim/search.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index faa14dfaf4..5a53122739 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2995,6 +2995,7 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, assert(numMatches > 0); // suppress clang "result of operation is garbage" // Initialize score int score = 100; + bool is_exact_match = true; // Apply leading letter penalty int penalty = LEADING_LETTER_PENALTY * (int)matches[0]; @@ -3048,6 +3049,14 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, // First letter score += FIRST_LETTER_BONUS; } + // Check exact match condition + if (currIdx != (uint32_t)i) { + is_exact_match = false; + } + } + // Boost score for exact matches + if (is_exact_match && numMatches == strSz) { + score += 100; } return score; } -- cgit From a8b6fa07c4d9143f3bd279ce8fd87e8121da16e1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 22 Jan 2025 09:28:27 +0800 Subject: fix(search): avoid quadratic time complexity when computing fuzzy score (#32153) --- src/nvim/search.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index 5a53122739..6e87b07d06 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2993,6 +2993,8 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { assert(numMatches > 0); // suppress clang "result of operation is garbage" + const char *p = str; + uint32_t sidx = 0; // Initialize score int score = 100; bool is_exact_match = true; @@ -3026,12 +3028,12 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, // Check for bonuses based on neighbor character value if (currIdx > 0) { // Camel case - const char *p = str; int neighbor = ' '; - for (uint32_t sidx = 0; sidx < currIdx; sidx++) { + while (sidx < currIdx) { neighbor = utf_ptr2char(p); MB_PTR_ADV(p); + sidx++; } const int curr = utf_ptr2char(p); -- cgit From a66f6add29fd8b2ee352c6089ceca6ab4f522385 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 22 Jan 2025 10:55:41 +0800 Subject: vim-patch:9.1.1046: fuzzymatching doesn't prefer matching camelcase (#32155) Problem: fuzzymatching doesn't prefer matching camelcase (Tomasz N) Solution: Add extra score when case matches (glepnir) fixes: vim/vim#16434 closes: vim/vim#16439 https://github.com/vim/vim/commit/9dfc7e5e6169594f6f4607ef1ba9dd347a9194d2 Co-authored-by: glepnir --- src/nvim/search.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'src/nvim/search.c') diff --git a/src/nvim/search.c b/src/nvim/search.c index 6e87b07d06..9f8ceae2a0 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2973,6 +2973,10 @@ typedef struct { #define CAMEL_BONUS 30 /// bonus if the first letter is matched #define FIRST_LETTER_BONUS 15 +/// bonus if exact match +#define EXACT_MATCH_BONUS 100 +/// bonus if case match when no ignorecase +#define CASE_MATCH_BONUS 25 /// penalty applied for every letter in str before the first match #define LEADING_LETTER_PENALTY (-5) /// maximum penalty for leading letters @@ -2988,16 +2992,23 @@ typedef struct { /// Compute a score for a fuzzy matched string. The matching character locations /// are in "matches". -static int fuzzy_match_compute_score(const char *const str, const int strSz, - const uint32_t *const matches, const int numMatches) +static int fuzzy_match_compute_score(const char *const fuzpat, const char *const str, + const int strSz, const uint32_t *const matches, + const int numMatches) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { assert(numMatches > 0); // suppress clang "result of operation is garbage" const char *p = str; uint32_t sidx = 0; + bool is_exact_match = true; + const char *const orig_fuzpat = fuzpat - numMatches; + const char *curpat = orig_fuzpat; + int pat_idx = 0; + // Track consecutive camel case matches + int consecutive_camel = 0; + // Initialize score int score = 100; - bool is_exact_match = true; // Apply leading letter penalty int penalty = LEADING_LETTER_PENALTY * (int)matches[0]; @@ -3013,6 +3024,7 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, // Apply ordering bonuses for (int i = 0; i < numMatches; i++) { const uint32_t currIdx = matches[i]; + bool is_camel = false; if (i > 0) { const uint32_t prevIdx = matches[i - 1]; @@ -3022,9 +3034,12 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, score += SEQUENTIAL_BONUS; } else { score += GAP_PENALTY * (int)(currIdx - prevIdx); + // Reset consecutive camel count on gap + consecutive_camel = 0; } } + int curr; // Check for bonuses based on neighbor character value if (currIdx > 0) { // Camel case @@ -3035,10 +3050,19 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, MB_PTR_ADV(p); sidx++; } - const int curr = utf_ptr2char(p); + curr = utf_ptr2char(p); + // Enhanced camel case scoring if (mb_islower(neighbor) && mb_isupper(curr)) { - score += CAMEL_BONUS; + score += CAMEL_BONUS * 2; // Double the camel case bonus + is_camel = true; + consecutive_camel++; + // Additional bonus for consecutive camel + if (consecutive_camel > 1) { + score += CAMEL_BONUS; + } + } else { + consecutive_camel = 0; } // Bonus if the match follows a separator character @@ -3050,16 +3074,36 @@ static int fuzzy_match_compute_score(const char *const str, const int strSz, } else { // First letter score += FIRST_LETTER_BONUS; + curr = utf_ptr2char(p); + } + + // Case matching bonus + if (mb_isalpha(curr)) { + while (pat_idx < i && *curpat) { + MB_PTR_ADV(curpat); + pat_idx++; + } + + if (curr == utf_ptr2char(curpat)) { + score += CASE_MATCH_BONUS; + // Extra bonus for exact case match in camel + if (is_camel) { + score += CASE_MATCH_BONUS / 2; + } + } } + // Check exact match condition if (currIdx != (uint32_t)i) { is_exact_match = false; } } + // Boost score for exact matches if (is_exact_match && numMatches == strSz) { - score += 100; + score += EXACT_MATCH_BONUS; } + return score; } @@ -3138,7 +3182,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s // Calculate score if (matched) { - *outScore = fuzzy_match_compute_score(strBegin, strLen, matches, nextMatch); + *outScore = fuzzy_match_compute_score(fuzpat, strBegin, strLen, matches, nextMatch); } // Return best result -- cgit