vim-patch:8.2.4465: fuzzy completion does not order matches properly

Problem:    Fuzzy completion does not order matches properly.
Solution:   Do not use regular expression match. (Yegappan Lakshmanan,
            closes vim/vim#9843)

5ec633b9b0

Nvim's ExpandGeneric() was refactored to eliminate looping for "round",
so the patch has been adapted.

fuzzy_match_str() change was already applied earlier.

In Test_wildoptions_fuzzy(), test for NvimParenthesis over MatchParen
for :syntax list, as the fuzzy matching algorithm prefers the former
(even in Vim).

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
Sean Dewar 2022-02-27 04:36:04 +00:00 committed by zeertzjq
parent 6734dd2503
commit 0c689fec8e
2 changed files with 61 additions and 25 deletions

View File

@ -2765,8 +2765,14 @@ static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, char ***matches, i
if (*str == NUL) { // skip empty strings if (*str == NUL) { // skip empty strings
continue; continue;
} }
if (vim_regexec(regmatch, str, (colnr_T)0)
|| (fuzzy && fuzzy_match_str(str, fuzzystr) != 0)) { bool match;
if (!fuzzy) {
match = vim_regexec(regmatch, str, (colnr_T)0);
} else {
match = fuzzy_match_str(str, fuzzystr) != 0;
}
if (match) {
count++; count++;
} }
} }
@ -2792,28 +2798,37 @@ static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, char ***matches, i
if (*str == NUL) { // Skip empty strings. if (*str == NUL) { // Skip empty strings.
continue; continue;
} }
int score;
if (vim_regexec(regmatch, str, (colnr_T)0) bool match;
|| (fuzzy && ((score = fuzzy_match_str(str, fuzzystr)) != 0))) { int score = 0;
if (escaped) { if (!fuzzy) {
str = vim_strsave_escaped(str, " \t\\."); match = vim_regexec(regmatch, str, (colnr_T)0);
} else { } else {
str = xstrdup(str); score = fuzzy_match_str(str, fuzzystr);
} match = (score != 0);
if (fuzzy) { }
fuzmatch[count].idx = (int)count; if (!match) {
fuzmatch[count].str = str; continue;
fuzmatch[count].score = score; }
} else {
(*matches)[count] = str; if (escaped) {
} str = vim_strsave_escaped(str, " \t\\.");
count++; } else {
if (func == get_menu_names) { str = xstrdup(str);
// Test for separator added by get_menu_names(). }
str += strlen(str) - 1; if (fuzzy) {
if (*str == '\001') { fuzmatch[count].idx = (int)count;
*str = '.'; fuzmatch[count].str = str;
} fuzmatch[count].score = score;
} else {
(*matches)[count] = str;
}
count++;
if (func == get_menu_names) {
// Test for separator added by get_menu_names().
str += strlen(str) - 1;
if (*str == '\001') {
*str = '.';
} }
} }
} }

View File

@ -2941,7 +2941,9 @@ func Test_wildoptions_fuzzy()
call assert_equal('"syntax list mpar', @:) call assert_equal('"syntax list mpar', @:)
set wildoptions=fuzzy set wildoptions=fuzzy
call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx') call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx')
call assert_equal('"syntax list MatchParen', @:) " Fuzzy match favours NvimParenthesis over MatchParen
" call assert_equal('"syntax list MatchParen', @:)
call assert_equal('"syntax list NvimParenthesis', @:)
" :syntime suboptions fuzzy completion " :syntime suboptions fuzzy completion
if has('profile') if has('profile')
@ -2968,6 +2970,25 @@ func Test_wildoptions_fuzzy()
call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx') call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx')
call assert_equal('"let SomeVariable', @:) call assert_equal('"let SomeVariable', @:)
" Test for sorting the results by the best match
%bw!
command T123format :
command T123goformat :
command T123TestFOrmat :
command T123fendoff :
command T123state :
command T123FendingOff :
set wildoptions=fuzzy
call feedkeys(":T123fo\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"T123format T123TestFOrmat T123FendingOff T123goformat T123fendoff', @:)
delcommand T123format
delcommand T123goformat
delcommand T123TestFOrmat
delcommand T123fendoff
delcommand T123state
delcommand T123FendingOff
%bw
set wildoptions& set wildoptions&
%bw! %bw!
endfunc endfunc