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 #9843)
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 909706d..94781f8 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -2633,6 +2633,7 @@
int score = 0;
int fuzzy = (fuzzystr != NULL);
int funcsort = FALSE;
+ int match;
// do this loop twice:
// round == 0: count the number of matching names
@@ -2647,44 +2648,52 @@
if (*str == NUL) // skip empty strings
continue;
- if (vim_regexec(regmatch, str, (colnr_T)0) ||
- (fuzzy && ((score = fuzzy_match_str(str, fuzzystr)) != 0)))
+ if (!fuzzy)
+ match = vim_regexec(regmatch, str, (colnr_T)0);
+ else
{
- if (round)
- {
- if (escaped)
- str = vim_strsave_escaped(str, (char_u *)" \t\\.");
- else
- str = vim_strsave(str);
- if (str == NULL)
- {
- FreeWild(count, *matches);
- if (fuzzy)
- fuzmatch_str_free(fuzmatch, count);
- *numMatches = 0;
- *matches = NULL;
- return FAIL;
- }
- if (fuzzy)
- {
- fuzmatch[count].idx = count;
- fuzmatch[count].str = str;
- fuzmatch[count].score = score;
- }
- else
- (*matches)[count] = str;
-# ifdef FEAT_MENU
- if (func == get_menu_names && str != NULL)
- {
- // test for separator added by get_menu_names()
- str += STRLEN(str) - 1;
- if (*str == '\001')
- *str = '.';
- }
-# endif
- }
- ++count;
+ score = fuzzy_match_str(str, fuzzystr);
+ match = (score != 0);
}
+
+ if (!match)
+ continue;
+
+ if (round)
+ {
+ if (escaped)
+ str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+ else
+ str = vim_strsave(str);
+ if (str == NULL)
+ {
+ if (fuzzy)
+ fuzmatch_str_free(fuzmatch, count);
+ else if (count > 0)
+ FreeWild(count, *matches);
+ *numMatches = 0;
+ *matches = NULL;
+ return FAIL;
+ }
+ if (fuzzy)
+ {
+ fuzmatch[count].idx = count;
+ fuzmatch[count].str = str;
+ fuzmatch[count].score = score;
+ }
+ else
+ (*matches)[count] = str;
+# ifdef FEAT_MENU
+ if (func == get_menu_names && str != NULL)
+ {
+ // test for separator added by get_menu_names()
+ str += STRLEN(str) - 1;
+ if (*str == '\001')
+ *str = '.';
+ }
+# endif
+ }
+ ++count;
}
if (round == 0)
{
diff --git a/src/search.c b/src/search.c
index 00a9fdf..063058d 100644
--- a/src/search.c
+++ b/src/search.c
@@ -5001,7 +5001,7 @@
fuzzy_match_str(char_u *str, char_u *pat)
{
int score = 0;
- int_u matchpos[256];
+ int_u matchpos[MAX_FUZZY_MATCHES];
if (str == NULL || pat == NULL)
return 0;
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 1ee0d71..73d39e3 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -2757,6 +2757,25 @@
call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx')
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&
%bw!
endfunc
diff --git a/src/version.c b/src/version.c
index 69be8cd..94479e3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4465,
+/**/
4464,
/**/
4463,