Patch 8.2.4765
Problem:    Function matchfuzzy() sorts too many items.
Solution:   Only put matches in the array. (Yegappan Lakshmanan,
            closes #10208)
Files:      src/search.c


*** ../vim-8.2.4764/src/search.c        2022-04-16 12:34:45.481217715 +0100
--- src/search.c        2022-04-16 20:38:22.925237190 +0100
***************
*** 4642,4648 ****
   */
      static void
  fuzzy_match_in_list(
!       list_T          *items,
        char_u          *str,
        int             matchseq,
        char_u          *key,
--- 4642,4648 ----
   */
      static void
  fuzzy_match_in_list(
!       list_T          *l,
        char_u          *str,
        int             matchseq,
        char_u          *key,
***************
*** 4652,4697 ****
        long            max_matches)
  {
      long      len;
!     fuzzyItem_T       *ptrs;
      listitem_T        *li;
      long      i = 0;
!     long      found_match = 0;
      int_u     matches[MAX_FUZZY_MATCHES];
  
!     len = list_len(items);
      if (len == 0)
        return;
  
!     // TODO: when using a limit use that instead of "len"
!     ptrs = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
!     if (ptrs == NULL)
        return;
  
      // For all the string items in items, get the fuzzy matching score
!     FOR_ALL_LIST_ITEMS(items, li)
      {
        int             score;
        char_u          *itemstr;
        typval_T        rettv;
  
!       ptrs[i].idx = i;
!       ptrs[i].item = li;
!       ptrs[i].score = SCORE_NONE;
! 
!       // TODO: instead of putting all items in ptrs[] should only add
!       // matching items there.
!       if (max_matches > 0 && found_match >= max_matches)
!       {
!           i++;
!           continue;
!       }
  
        itemstr = NULL;
        rettv.v_type = VAR_UNKNOWN;
        if (li->li_tv.v_type == VAR_STRING)     // list of strings
            itemstr = li->li_tv.vval.v_string;
        else if (li->li_tv.v_type == VAR_DICT
!                                 && (key != NULL || item_cb->cb_name != NULL))
        {
            // For a dict, either use the specified key to lookup the string or
            // use the specified callback function to get the string.
--- 4652,4689 ----
        long            max_matches)
  {
      long      len;
!     fuzzyItem_T       *items;
      listitem_T        *li;
      long      i = 0;
!     long      match_count = 0;
      int_u     matches[MAX_FUZZY_MATCHES];
  
!     len = list_len(l);
      if (len == 0)
        return;
+     if (max_matches > 0 && len > max_matches)
+       len = max_matches;
  
!     items = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
!     if (items == NULL)
        return;
  
      // For all the string items in items, get the fuzzy matching score
!     FOR_ALL_LIST_ITEMS(l, li)
      {
        int             score;
        char_u          *itemstr;
        typval_T        rettv;
  
!       if (max_matches > 0 && match_count >= max_matches)
!           break;
  
        itemstr = NULL;
        rettv.v_type = VAR_UNKNOWN;
        if (li->li_tv.v_type == VAR_STRING)     // list of strings
            itemstr = li->li_tv.vval.v_string;
        else if (li->li_tv.v_type == VAR_DICT
!                               && (key != NULL || item_cb->cb_name != NULL))
        {
            // For a dict, either use the specified key to lookup the string or
            // use the specified callback function to get the string.
***************
*** 4717,4724 ****
  
        if (itemstr != NULL
                && fuzzy_match(itemstr, str, matchseq, &score, matches,
!                   sizeof(matches) / sizeof(matches[0])))
        {
            // Copy the list of matching positions in itemstr to a list, if
            // 'retmatchpos' is set.
            if (retmatchpos)
--- 4709,4720 ----
  
        if (itemstr != NULL
                && fuzzy_match(itemstr, str, matchseq, &score, matches,
!                                                       MAX_FUZZY_MATCHES))
        {
+           items[match_count].idx = match_count;
+           items[match_count].item = li;
+           items[match_count].score = score;
+ 
            // Copy the list of matching positions in itemstr to a list, if
            // 'retmatchpos' is set.
            if (retmatchpos)
***************
*** 4726,4733 ****
                int     j = 0;
                char_u  *p;
  
!               ptrs[i].lmatchpos = list_alloc();
!               if (ptrs[i].lmatchpos == NULL)
                    goto done;
  
                p = str;
--- 4722,4729 ----
                int     j = 0;
                char_u  *p;
  
!               items[match_count].lmatchpos = list_alloc();
!               if (items[match_count].lmatchpos == NULL)
                    goto done;
  
                p = str;
***************
*** 4735,4741 ****
                {
                    if (!VIM_ISWHITE(PTR2CHAR(p)))
                    {
!                       if (list_append_number(ptrs[i].lmatchpos,
                                    matches[j]) == FAIL)
                            goto done;
                        j++;
--- 4731,4737 ----
                {
                    if (!VIM_ISWHITE(PTR2CHAR(p)))
                    {
!                       if (list_append_number(items[match_count].lmatchpos,
                                    matches[j]) == FAIL)
                            goto done;
                        j++;
***************
*** 4746,4764 ****
                        ++p;
                }
            }
!           ptrs[i].score = score;
!           ++found_match;
        }
-       ++i;
        clear_tv(&rettv);
      }
  
!     if (found_match > 0)
      {
!       list_T          *l;
  
        // Sort the list by the descending order of the match score
!       qsort((void *)ptrs, (size_t)len, sizeof(fuzzyItem_T),
                fuzzy_match_item_compare);
  
        // For matchfuzzy(), return a list of matched strings.
--- 4742,4758 ----
                        ++p;
                }
            }
!           ++match_count;
        }
        clear_tv(&rettv);
      }
  
!     if (match_count > 0)
      {
!       list_T          *retlist;
  
        // Sort the list by the descending order of the match score
!       qsort((void *)items, (size_t)match_count, sizeof(fuzzyItem_T),
                fuzzy_match_item_compare);
  
        // For matchfuzzy(), return a list of matched strings.
***************
*** 4773,4789 ****
            li = list_find(fmatchlist, 0);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           l = li->li_tv.vval.v_list;
        }
        else
!           l = fmatchlist;
  
        // Copy the matching strings with a valid score to the return list
!       for (i = 0; i < len; i++)
        {
!           if (ptrs[i].score == SCORE_NONE)
                break;
!           list_append_tv(l, &ptrs[i].item->li_tv);
        }
  
        // next copy the list of matching positions
--- 4767,4783 ----
            li = list_find(fmatchlist, 0);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           retlist = li->li_tv.vval.v_list;
        }
        else
!           retlist = fmatchlist;
  
        // Copy the matching strings with a valid score to the return list
!       for (i = 0; i < match_count; i++)
        {
!           if (items[i].score == SCORE_NONE)
                break;
!           list_append_tv(retlist, &items[i].item->li_tv);
        }
  
        // next copy the list of matching positions
***************
*** 4792,4805 ****
            li = list_find(fmatchlist, -2);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           l = li->li_tv.vval.v_list;
  
!           for (i = 0; i < len; i++)
            {
!               if (ptrs[i].score == SCORE_NONE)
                    break;
!               if (ptrs[i].lmatchpos != NULL
!                            && list_append_list(l, ptrs[i].lmatchpos) == FAIL)
                    goto done;
            }
  
--- 4786,4800 ----
            li = list_find(fmatchlist, -2);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           retlist = li->li_tv.vval.v_list;
  
!           for (i = 0; i < match_count; i++)
            {
!               if (items[i].score == SCORE_NONE)
                    break;
!               if (items[i].lmatchpos != NULL
!                       && list_append_list(retlist, items[i].lmatchpos)
!                                                               == FAIL)
                    goto done;
            }
  
***************
*** 4807,4825 ****
            li = list_find(fmatchlist, -1);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           l = li->li_tv.vval.v_list;
!           for (i = 0; i < len; i++)
            {
!               if (ptrs[i].score == SCORE_NONE)
                    break;
!               if (list_append_number(l, ptrs[i].score) == FAIL)
                    goto done;
            }
        }
      }
  
  done:
!     vim_free(ptrs);
  }
  
  /*
--- 4802,4820 ----
            li = list_find(fmatchlist, -1);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
!           retlist = li->li_tv.vval.v_list;
!           for (i = 0; i < match_count; i++)
            {
!               if (items[i].score == SCORE_NONE)
                    break;
!               if (list_append_number(retlist, items[i].score) == FAIL)
                    goto done;
            }
        }
      }
  
  done:
!     vim_free(items);
  }
  
  /*
*** ../vim-8.2.4764/src/version.c       2022-04-16 20:04:26.174152095 +0100
--- src/version.c       2022-04-16 20:42:16.976813902 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4765,
  /**/

-- 
Often you're less important than your furniture.  If you think about it, you
can get fired but your furniture stays behind, gainfully employed at the
company that didn't need _you_ anymore.
                                (Scott Adams - The Dilbert principle)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220416194345.4960B1C05DA%40moolenaar.net.

Raspunde prin e-mail lui