diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/search.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-rahm.tar.gz rneovim-rahm.tar.bz2 rneovim-rahm.zip |
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r-- | src/nvim/search.c | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index debc5697d1..9f8ceae2a0 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" @@ -1203,6 +1202,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 @@ -1422,7 +1422,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, @@ -2349,7 +2349,7 @@ void showmatch(int c) } if ((lpos = findmatch(NULL, NUL)) == NULL) { // no match, so beep - vim_beep(BO_MATCH); + vim_beep(kOptBoFlagShowmatch); return; } @@ -2534,7 +2534,7 @@ int current_search(int count, bool forward) } } - if (fdo_flags & FDO_SEARCH && KeyTyped) { + if (fdo_flags & kOptFdoFlagSearch && KeyTyped) { foldOpenCursor(); } @@ -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,11 +2992,21 @@ 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; @@ -3010,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]; @@ -3019,23 +3034,35 @@ 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 - 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); + 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 @@ -3047,8 +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 += EXACT_MATCH_BONUS; + } + return score; } @@ -3127,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 |