vim-patch:8.2.1872: matchfuzzy() does not prefer sequential matches

Problem:    Matchfuzzy() does not prefer sequential matches.
Solution:   Give sequential matches a higher bonus. (Christian Brabandt,
            closes vim/vim#7140)
e9f9f16387
This commit is contained in:
Sean Dewar 2022-01-01 21:12:53 +00:00
parent 960ea01972
commit 8313d31e4a
No known key found for this signature in database
GPG Key ID: 08CC2C83AD41B581
2 changed files with 21 additions and 7 deletions

View File

@ -4818,8 +4818,9 @@ typedef struct {
list_T *lmatchpos; list_T *lmatchpos;
} fuzzyItem_T; } fuzzyItem_T;
/// bonus for adjacent matches /// bonus for adjacent matches; this is higher than SEPARATOR_BONUS so that
#define SEQUENTIAL_BONUS 15 /// matching a whole word is preferred.
#define SEQUENTIAL_BONUS 40
/// bonus if match occurs after a separator /// bonus if match occurs after a separator
#define SEPARATOR_BONUS 30 #define SEPARATOR_BONUS 30
/// bonus if match is uppercase and prev is lower /// bonus if match is uppercase and prev is lower

View File

@ -20,7 +20,7 @@ func Test_matchfuzzy()
call assert_equal(['aabbaa', 'aaabbbaaa', 'aaaabbbbaaaa', 'aba'], matchfuzzy(['aba', 'aabbaa', 'aaabbbaaa', 'aaaabbbbaaaa'], 'aa')) call assert_equal(['aabbaa', 'aaabbbaaa', 'aaaabbbbaaaa', 'aba'], matchfuzzy(['aba', 'aabbaa', 'aaabbbaaa', 'aaaabbbbaaaa'], 'aa'))
call assert_equal(['one'], matchfuzzy(['one', 'two'], 'one')) call assert_equal(['one'], matchfuzzy(['one', 'two'], 'one'))
call assert_equal(['oneTwo', 'onetwo'], matchfuzzy(['onetwo', 'oneTwo'], 'oneTwo')) call assert_equal(['oneTwo', 'onetwo'], matchfuzzy(['onetwo', 'oneTwo'], 'oneTwo'))
call assert_equal(['one_two', 'onetwo'], matchfuzzy(['onetwo', 'one_two'], 'oneTwo')) call assert_equal(['onetwo', 'one_two'], matchfuzzy(['onetwo', 'one_two'], 'oneTwo'))
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)))
@ -29,7 +29,11 @@ func Test_matchfuzzy()
" preference for camel case match " preference for camel case match
call assert_equal(['oneTwo', 'onetwo'], ['onetwo', 'oneTwo']->matchfuzzy('onetwo')) call assert_equal(['oneTwo', 'onetwo'], ['onetwo', 'oneTwo']->matchfuzzy('onetwo'))
" preference for match after a separator (_ or space) " preference for match after a separator (_ or space)
call assert_equal(['one_two', 'one two', 'onetwo'], ['onetwo', 'one_two', 'one two']->matchfuzzy('onetwo')) if has("win32")
call assert_equal(['onetwo', 'one two', 'one_two'], ['onetwo', 'one_two', 'one two']->matchfuzzy('onetwo'))
else
call assert_equal(['onetwo', 'one_two', 'one two'], ['onetwo', 'one_two', 'one two']->matchfuzzy('onetwo'))
endif
" preference for leading letter match " preference for leading letter match
call assert_equal(['onetwo', 'xonetwo'], ['xonetwo', 'onetwo']->matchfuzzy('onetwo')) call assert_equal(['onetwo', 'xonetwo'], ['xonetwo', 'onetwo']->matchfuzzy('onetwo'))
" preference for sequential match " preference for sequential match
@ -38,6 +42,8 @@ func Test_matchfuzzy()
call assert_equal(['xonetwo', 'xxonetwo'], ['xxonetwo', 'xonetwo']->matchfuzzy('onetwo')) call assert_equal(['xonetwo', 'xxonetwo'], ['xxonetwo', 'xonetwo']->matchfuzzy('onetwo'))
" total non-matching letter(s) penalty " total non-matching letter(s) penalty
call assert_equal(['one', 'onex', 'onexx'], ['onexx', 'one', 'onex']->matchfuzzy('one')) call assert_equal(['one', 'onex', 'onexx'], ['onexx', 'one', 'onex']->matchfuzzy('one'))
" prefer complete matches over separator matches
call assert_equal(['.vim/vimrc', '.vim/vimrc_colors', '.vim/v_i_m_r_c'], ['.vim/vimrc', '.vim/vimrc_colors', '.vim/v_i_m_r_c']->matchfuzzy('vimrc'))
%bw! %bw!
eval ['somebuf', 'anotherone', 'needle', 'yetanotherone']->map({_, v -> bufadd(v) + bufload(v)}) eval ['somebuf', 'anotherone', 'needle', 'yetanotherone']->map({_, v -> bufadd(v) + bufload(v)})
@ -148,9 +154,16 @@ func Test_matchfuzzy_mbyte()
" preference for camel case match " preference for camel case match
call assert_equal(['oneĄwo', 'oneąwo'], call assert_equal(['oneĄwo', 'oneąwo'],
\ ['oneąwo', 'oneĄwo']->matchfuzzy('oneąwo')) \ ['oneąwo', 'oneĄwo']->matchfuzzy('oneąwo'))
" preference for match after a separator (_ or space) " preference for complete match then match after separator (_ or space)
call assert_equal(['Ⅱa_bㄟㄠ', 'Ⅱa bㄟㄠ', 'Ⅱabㄟㄠ'], if has("win32")
\ ['Ⅱabㄟㄠ', 'Ⅱa_bㄟㄠ', 'Ⅱa bㄟㄠ']->matchfuzzy('Ⅱabㄟㄠ')) " order is different between Windows and Unix :(
" It's important that the complete match is first
call assert_equal(['Ⅱabㄟㄠ', 'Ⅱa bㄟㄠ', 'Ⅱa_bㄟㄠ'],
\ ['Ⅱabㄟㄠ', 'Ⅱa_bㄟㄠ', 'Ⅱa bㄟㄠ']->matchfuzzy('Ⅱabㄟㄠ'))
else
call assert_equal(['Ⅱabㄟㄠ'] + sort(['Ⅱa_bㄟㄠ', 'Ⅱa bㄟㄠ']),
\ ['Ⅱabㄟㄠ', 'Ⅱa bㄟㄠ', 'Ⅱa_bㄟㄠ']->matchfuzzy('Ⅱabㄟㄠ'))
endif
" preference for leading letter match " preference for leading letter match
call assert_equal(['ŗŝţũŵż', 'xŗŝţũŵż'], call assert_equal(['ŗŝţũŵż', 'xŗŝţũŵż'],
\ ['xŗŝţũŵż', 'ŗŝţũŵż']->matchfuzzy('ŗŝţũŵż')) \ ['xŗŝţũŵż', 'ŗŝţũŵż']->matchfuzzy('ŗŝţũŵż'))