From bcba067dc212942a84c8dacf79f00c7288436a2b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 10 Jun 2025 08:47:14 +0800 Subject: [PATCH] vim-patch:9.1.1445: negative matchfuzzy scores although there is a match (#34409) Problem: negative matchfuzzy scores although there is a match (Maxim Kim) Solution: reset the score if a match has been found but the score is negative (Girish Palya) The fuzzy algorithm may miss some matches in long strings due to recursion limits. As a result, the score can end up negative even when matches exist. In such cases, reset the score to ensure it is non-negative. fixes: #vim/vim#17449 closes: vim/vim#17469 https://github.com/vim/vim/commit/328332b0b03ff6a709ed319b83429390ee8394d8 Co-authored-by: Girish Palya --- src/nvim/search.c | 5 +++++ test/old/testdir/test_matchfuzzy.vim | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvim/search.c b/src/nvim/search.c index 2a5b912133..28c0f42162 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3021,6 +3021,11 @@ static int fuzzy_match_compute_score(const char *const fuzpat, const char *const // Apply unmatched penalty const int unmatched = strSz - numMatches; score += UNMATCHED_LETTER_PENALTY * unmatched; + // In a long string, not all matches may be found due to the recursion limit. + // If at least one match is found, reset the score to a non-negative value. + if (score < 0 && numMatches > 0) { + score = 0; + } // Apply ordering bonuses for (int i = 0; i < numMatches; i++) { diff --git a/test/old/testdir/test_matchfuzzy.vim b/test/old/testdir/test_matchfuzzy.vim index 10480f446d..5185db853a 100644 --- a/test/old/testdir/test_matchfuzzy.vim +++ b/test/old/testdir/test_matchfuzzy.vim @@ -129,7 +129,7 @@ func Test_matchfuzzypos() call assert_equal([[], [], []], matchfuzzypos([], 'abc')) " match in a long string - call assert_equal([[repeat('x', 300) .. 'abc'], [[300, 301, 302]], [-60]], + call assert_equal([[repeat('x', 300) .. 'abc'], [[300, 301, 302]], [155]], \ matchfuzzypos([repeat('x', 300) .. 'abc'], 'abc')) " preference for camel case match @@ -265,7 +265,7 @@ func Test_matchfuzzypos_mbyte() call assert_equal([[], [], []], ['세 마리의 작은 돼지', '마리의', '마리의 작은', '작은 돼지']->matchfuzzypos('파란 하늘')) " match in a long string - call assert_equal([[repeat('ぶ', 300) .. 'ẼẼẼ'], [[300, 301, 302]], [-110]], + call assert_equal([[repeat('ぶ', 300) .. 'ẼẼẼ'], [[300, 301, 302]], [105]], \ matchfuzzypos([repeat('ぶ', 300) .. 'ẼẼẼ'], 'ẼẼẼ')) " preference for camel case match call assert_equal([['xѳѵҁxxѳѴҁ'], [[6, 7, 8]], [219]], matchfuzzypos(['xѳѵҁxxѳѴҁ'], 'ѳѵҁ'))