patch 9.1.0479: fuzzy_match_str_with_pos() does unnecessary list operations

Problem:  fuzzy_match_str_with_pos() does unnecessary list operations.
Solution: Use fuzzy_match() directly (zeertzjq).

closes: #14987

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 00b0006..dd1a6ec 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -463,8 +463,8 @@
             // Handle fuzzy matching
             for (i = 0; i < ga->ga_len; i++)
             {
-                int *match_pos = ((int *)ga->ga_data) + i;
-                int actual_char_pos = 0;
+                int_u *match_pos = ((int_u *)ga->ga_data) + i;
+                int_u actual_char_pos = 0;
                 char_u *temp_ptr = text;
                 while (temp_ptr < ptr)
                 {
diff --git a/src/search.c b/src/search.c
index 20bf399..0b39d90 100644
--- a/src/search.c
+++ b/src/search.c
@@ -5101,115 +5101,39 @@
 {
 #ifdef FEAT_SEARCH_EXTRA
     int		    score = 0;
-    garray_T	    *match_positions = ALLOC_ONE(garray_T);
-    typval_T	    tv_str;
-    list_T	    *l = NULL;
-    list_T	    *retlist = NULL;
-    list_T	    *match_str_list = NULL;
-    list_T	    *match_pos_list = NULL;
-    list_T	    *match_score_list = NULL;
-    listitem_T	    *score_item = NULL;
-    listitem_T	    *positions_item = NULL;
-    list_T	    *positions_outer_list = NULL;
-    listitem_T	    *outer_li = NULL;
-    list_T	    *positions_inner_list = NULL;
+    garray_T	    *match_positions = NULL;
+    int_u	    matches[MAX_FUZZY_MATCHES];
+    int		    j = 0;
 
+    if (str == NULL || pat == NULL)
+        return NULL;
+
+    match_positions = ALLOC_ONE(garray_T);
     if (match_positions == NULL)
         return NULL;
-    ga_init2(match_positions, sizeof(int), 10);
-    if (str == NULL || pat == NULL)
+    ga_init2(match_positions, sizeof(int_u), 10);
+
+    if (!fuzzy_match(str, pat, FALSE, &score, matches, MAX_FUZZY_MATCHES)
+	    || score == 0)
     {
-        ga_clear(match_positions);
-        return NULL;
-    }
-    l = list_alloc();
-    if (l == NULL)
-    {
-        ga_clear(match_positions);
-        return NULL;
+	ga_clear(match_positions);
+	vim_free(match_positions);
+	return NULL;
     }
 
-    tv_str.v_type = VAR_STRING;
-    tv_str.vval.v_string = vim_strsave(str);
-    if (tv_str.vval.v_string == NULL || list_append_tv(l, &tv_str) == FAIL)
-        goto cleanup;
-
-    retlist = list_alloc();
-    if (retlist == NULL)
-        goto cleanup;
-
-    match_str_list = list_alloc();
-    match_pos_list = list_alloc();
-    match_score_list = list_alloc();
-    if (match_str_list == NULL || match_pos_list == NULL || match_score_list == NULL)
-        goto cleanup;
-
-    list_append_list(retlist, match_str_list);
-    list_append_list(retlist, match_pos_list);
-    list_append_list(retlist, match_score_list);
-
-    fuzzy_match_in_list(l, pat, FALSE, NULL, NULL, TRUE, retlist, 1);
-
-    if (retlist->lv_len != 3)
-        goto cleanup;
-
-    score_item = list_find(retlist, 2);
-    if (score_item != NULL && score_item->li_tv.v_type == VAR_LIST)
+    for (char_u *p = pat; *p != NUL; MB_PTR_ADV(p))
     {
-        list_T *score_list = score_item->li_tv.vval.v_list;
-        if (score_list->lv_len > 0)
-        {
-            listitem_T *first_score_item = score_list->lv_first;
-            if (first_score_item != NULL && first_score_item->li_tv.v_type == VAR_NUMBER)
-                score = first_score_item->li_tv.vval.v_number;
-        }
-    }
-    if (score == 0)
-        goto cleanup;
-
-    positions_item = list_find(retlist, 1);
-    if (positions_item != NULL && positions_item->li_tv.v_type == VAR_LIST)
-    {
-        positions_outer_list = positions_item->li_tv.vval.v_list;
-        if (positions_outer_list->lv_len > 0)
-        {
-            outer_li = positions_outer_list->lv_first;
-            if (outer_li != NULL && outer_li->li_tv.v_type == VAR_LIST)
-            {
-                positions_inner_list = outer_li->li_tv.vval.v_list;
-                for (listitem_T *li = positions_inner_list->lv_first; li != NULL; li = li->li_next)
-                {
-                    if (li->li_tv.v_type == VAR_NUMBER)
-                    {
-                        int pos = li->li_tv.vval.v_number;
-                        ga_grow(match_positions, 1);
-                        ((int *)match_positions->ga_data)[match_positions->ga_len] = pos;
-                        match_positions->ga_len++;
-                    }
-                }
-            }
-        }
+	if (!VIM_ISWHITE(PTR2CHAR(p)))
+	{
+	    ga_grow(match_positions, 1);
+	    ((int_u *)match_positions->ga_data)[match_positions->ga_len] =
+								    matches[j];
+	    match_positions->ga_len++;
+	    j++;
+	}
     }
 
-    vim_free(tv_str.vval.v_string);
-    list_free(retlist);
-    list_free(l);
     return match_positions;
-
-cleanup:
-    vim_free(tv_str.vval.v_string);
-    if (match_str_list != NULL)
-        list_free(match_str_list);
-    if (match_pos_list != NULL)
-        list_free(match_pos_list);
-    if (match_score_list != NULL)
-        list_free(match_score_list);
-    if (retlist != NULL)
-        list_free(retlist);
-    if (l != NULL)
-        list_free(l);
-    ga_clear(match_positions);
-    return NULL;
 #else
     return NULL;
 #endif
diff --git a/src/version.c b/src/version.c
index 4b695c0..5addf1a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    479,
+/**/
     478,
 /**/
     477,