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

5a04999a74
This commit is contained in:
glepnir
2024-12-27 14:23:06 +08:00
committed by GitHub
parent 557f2d9700
commit 46c7faa00b
3 changed files with 14 additions and 2 deletions

View File

@ -1485,6 +1485,7 @@ criteria:
- Matches at a camel case character (e.g. Case in CamelCase)
- Matches after a path separator or a hyphen.
- The number of unmatched characters in a string.
- A full/exact match is preferred.
The matching string with the highest score is returned first.
For example, when you search for the "get pat" string using fuzzy matching, it

View File

@ -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;
}

View File

@ -23,6 +23,8 @@ func Test_matchfuzzy()
call assert_equal(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], matchfuzzy(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], 'aa'))
call assert_equal(256, matchfuzzy([repeat('a', 256)], repeat('a', 256))[0]->len())
call assert_equal([], matchfuzzy([repeat('a', 300)], repeat('a', 257)))
" full match has highest score
call assert_equal(['Cursor', 'lCursor'], matchfuzzy(["hello", "lCursor", "Cursor"], "Cursor"))
" matches with same score should not be reordered
let l = ['abc1', 'abc2', 'abc3']
call assert_equal(l, l->matchfuzzy('abc'))
@ -101,7 +103,7 @@ func Test_matchfuzzypos()
call assert_equal([['curl', 'world'], [[2,3], [2,3]], [128, 127]], matchfuzzypos(['world', 'curl'], 'rl'))
call assert_equal([['curl', 'world'], [[2,3], [2,3]], [128, 127]], matchfuzzypos(['world', 'one', 'curl'], 'rl'))
call assert_equal([['hello', 'hello world hello world'],
\ [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [275, 257]],
\ [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [375, 257]],
\ matchfuzzypos(['hello world hello world', 'hello', 'world'], 'hello'))
call assert_equal([['aaaaaaa'], [[0, 1, 2]], [191]], matchfuzzypos(['aaaaaaa'], 'aaa'))
call assert_equal([['a b'], [[0, 3]], [219]], matchfuzzypos(['a b'], 'a b'))
@ -136,7 +138,7 @@ func Test_matchfuzzypos()
call assert_equal([['foo bar baz'], [[0, 1, 2, 3, 4, 5, 10]], [326]], ['foo bar baz', 'foo', 'foo bar', 'baz bar']->matchfuzzypos('foo baz', {'matchseq': 1}))
call assert_equal([[], [], []], ['foo bar baz', 'foo', 'foo bar', 'baz bar']->matchfuzzypos('one two'))
call assert_equal([[], [], []], ['foo bar']->matchfuzzypos(" \t "))
call assert_equal([['grace'], [[1, 2, 3, 4, 2, 3, 4, 0, 1, 2, 3, 4]], [657]], ['grace']->matchfuzzypos('race ace grace'))
call assert_equal([['grace'], [[1, 2, 3, 4, 2, 3, 4, 0, 1, 2, 3, 4]], [757]], ['grace']->matchfuzzypos('race ace grace'))
let l = [{'id' : 5, 'val' : 'crayon'}, {'id' : 6, 'val' : 'camera'}]
call assert_equal([[{'id' : 6, 'val' : 'camera'}], [[0, 1, 2]], [192]],