changeset 27879:76e2115dddb8 v8.2.4465

patch 8.2.4465: fuzzy completion does not order matches properly Commit: https://github.com/vim/vim/commit/5ec633b9b0400519db60253cb5846e50394218b4 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri Feb 25 15:24:24 2022 +0000 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)
author Bram Moolenaar <Bram@vim.org>
date Fri, 25 Feb 2022 16:30:07 +0100
parents 223dc382d076
children e0715aa9f9a8
files src/cmdexpand.c src/search.c src/testdir/test_cmdline.vim src/version.c
diffstat 4 files changed, 63 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -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
 	    {
-		if (round)
+		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 (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 = '.';
-		    }
+		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;
 	    }
+	    ++count;
 	}
 	if (round == 0)
 	{
--- a/src/search.c
+++ b/src/search.c
@@ -5001,7 +5001,7 @@ fuzzy_match_func_sort(fuzmatch_str_T *fm
 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;
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -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
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4465,
+/**/
     4464,
 /**/
     4463,