patch 8.2.4465: fuzzy completion does not order matches properly v8.2.4465
authorYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 25 Feb 2022 15:24:24 +0000 (15:24 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 25 Feb 2022 15:24:24 +0000 (15:24 +0000)
Problem:    Fuzzy completion does not order matches properly.
Solution:   Do not use regular expression match. (Yegappan Lakshmanan,
            closes #9843)

src/cmdexpand.c
src/search.c
src/testdir/test_cmdline.vim
src/version.c

index 909706d1de9cf3cb9751d7c93b8d143949d23c7d..94781f82f0643b4f3beda0a42bb9068d15c76ebc 100644 (file)
@@ -2633,6 +2633,7 @@ ExpandGeneric(
     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 @@ ExpandGeneric(
            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
+           {
+               score = fuzzy_match_str(str, fuzzystr);
+               match = (score != 0);
+           }
+
+           if (!match)
+               continue;
+
+           if (round)
            {
-               if (round)
+               if (escaped)
+                   str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+               else
+                   str = vim_strsave(str);
+               if (str == NULL)
                {
-                   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;
+                       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
+               if (func == get_menu_names && str != NULL)
+               {
+                   // test for separator added by get_menu_names()
+                   str += STRLEN(str) - 1;
+                   if (*str == '\001')
+                       *str = '.';
                }
-               ++count;
+# endif
            }
+           ++count;
        }
        if (round == 0)
        {
index 00a9fdfc6df065ef4ba5c43c8bc4b3bf26261625..063058d326f09729ec7c8dfc99bcfa5c9574915c 100644 (file)
@@ -5001,7 +5001,7 @@ fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz)
 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;
index 1ee0d718e2b5b5ca6a9a55df471b7bfb8322bb96..73d39e39e083fd944b808cdf5f20ab645c47c598 100644 (file)
@@ -2757,6 +2757,25 @@ func Test_wildoptions_fuzzy()
   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
index 69be8cd054661658fe54f8d7a52e72050ab80f8d..94479e3ce58753e947f93614335f26e59cac5a67 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4465,
 /**/
     4464,
 /**/