0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.1.0963: fuzzy-matching does not prefer full match

Problem:  fuzzy-matching does not prefer full match
          (Maxim Kim)
Solution: add additional score for a full match
          (glepnir)

fixes: #15654
closes: #16300

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir 2024-12-26 15:38:39 +01:00 committed by Christian Brabandt
parent f07ae5b3bd
commit 5a04999a74
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
4 changed files with 16 additions and 3 deletions

View File

@ -1,4 +1,4 @@
*pattern.txt* For Vim version 9.1. Last change: 2024 Nov 09 *pattern.txt* For Vim version 9.1. Last change: 2024 Dec 26
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1504,6 +1504,7 @@ criteria:
- Matches at a camel case character (e.g. Case in CamelCase) - Matches at a camel case character (e.g. Case in CamelCase)
- Matches after a path separator or a hyphen. - Matches after a path separator or a hyphen.
- The number of unmatched characters in a string. - The number of unmatched characters in a string.
- A full/exact match is preferred.
The matching string with the highest score is returned first. The matching string with the highest score is returned first.
For example, when you search for the "get pat" string using fuzzy matching, it For example, when you search for the "get pat" string using fuzzy matching, it

View File

@ -4385,6 +4385,7 @@ fuzzy_match_compute_score(
int i; int i;
char_u *p = str; char_u *p = str;
int_u sidx = 0; int_u sidx = 0;
int is_exact_match = TRUE;
// Initialize score // Initialize score
score = 100; score = 100;
@ -4452,7 +4453,14 @@ fuzzy_match_compute_score(
// First letter // First letter
score += FIRST_LETTER_BONUS; score += FIRST_LETTER_BONUS;
} }
// Check exact match condition
if (currIdx != (int_u)i)
is_exact_match = FALSE;
} }
// Boost score for exact matches
if (is_exact_match && numMatches == strSz)
score += 100;
return score; return score;
} }

View File

@ -23,6 +23,8 @@ func Test_matchfuzzy()
call assert_equal(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], matchfuzzy(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], 'aa')) call assert_equal(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], matchfuzzy(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], 'aa'))
call assert_equal(256, matchfuzzy([repeat('a', 256)], repeat('a', 256))[0]->len()) call assert_equal(256, matchfuzzy([repeat('a', 256)], repeat('a', 256))[0]->len())
call assert_equal([], matchfuzzy([repeat('a', 300)], repeat('a', 257))) 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 " matches with same score should not be reordered
let l = ['abc1', 'abc2', 'abc3'] let l = ['abc1', 'abc2', 'abc3']
call assert_equal(l, l->matchfuzzy('abc')) call assert_equal(l, l->matchfuzzy('abc'))
@ -97,7 +99,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', 'curl'], 'rl'))
call assert_equal([['curl', 'world'], [[2,3], [2,3]], [128, 127]], matchfuzzypos(['world', 'one', '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'], 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')) \ matchfuzzypos(['hello world hello world', 'hello', 'world'], 'hello'))
call assert_equal([['aaaaaaa'], [[0, 1, 2]], [191]], matchfuzzypos(['aaaaaaa'], 'aaa')) call assert_equal([['aaaaaaa'], [[0, 1, 2]], [191]], matchfuzzypos(['aaaaaaa'], 'aaa'))
call assert_equal([['a b'], [[0, 3]], [219]], matchfuzzypos(['a b'], 'a b')) call assert_equal([['a b'], [[0, 3]], [219]], matchfuzzypos(['a b'], 'a b'))
@ -132,7 +134,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'], [[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 baz', 'foo', 'foo bar', 'baz bar']->matchfuzzypos('one two'))
call assert_equal([[], [], []], ['foo bar']->matchfuzzypos(" \t ")) 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'}] let l = [{'id' : 5, 'val' : 'crayon'}, {'id' : 6, 'val' : 'camera'}]
call assert_equal([[{'id' : 6, 'val' : 'camera'}], [[0, 1, 2]], [192]], call assert_equal([[{'id' : 6, 'val' : 'camera'}], [[0, 1, 2]], [192]],

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
963,
/**/ /**/
962, 962,
/**/ /**/