Patch 8.2.4760
Problem:    Using matchfuzzy() on a long list can take a while.
Solution:   Add a limit to the number of matches. (Yasuhiro Matsumoto,
            closes #10189)
Files:      runtime/doc/builtin.txt, src/search.c,
            src/testdir/test_matchfuzzy.vim


*** ../vim-8.2.4759/runtime/doc/builtin.txt     2022-04-12 12:54:06.917010952 
+0100
--- runtime/doc/builtin.txt     2022-04-16 12:32:02.928950392 +0100
***************
*** 5565,5571 ****
  
                If {list} is a list of dictionaries, then the optional {dict}
                argument supports the following additional items:
!                   key         key of the item which is fuzzy matched against
                                {str}. The value of this item should be a
                                string.
                    text_cb     |Funcref| that will be called for every item
--- 5583,5589 ----
  
                If {list} is a list of dictionaries, then the optional {dict}
                argument supports the following additional items:
!                   key         Key of the item which is fuzzy matched against
                                {str}. The value of this item should be a
                                string.
                    text_cb     |Funcref| that will be called for every item
***************
*** 5573,5578 ****
--- 5591,5598 ----
                                This should accept a dictionary item as the
                                argument and return the text for that item to
                                use for fuzzy matching.
+                   limit       Maximum number of matches in {list} to be
+                               returned.  Zero means no limit.
  
                {str} is treated as a literal string and regular expression
                matching is NOT supported.  The maximum supported {str} length
***************
*** 5585,5591 ****
                empty list is returned. If length of {str} is greater than
                256, then returns an empty list.
  
!               Refer to |fuzzy-match| for more information about fuzzy
                matching strings.
  
                Example: >
--- 5605,5614 ----
                empty list is returned. If length of {str} is greater than
                256, then returns an empty list.
  
!               When {limit} is given, matchfuzzy() will find up to this
!               number of matches in {list} and return them in sorted order.
! 
!               Refer to |fuzzy-matching| for more information about fuzzy
                matching strings.
  
                Example: >
*** ../vim-8.2.4759/src/search.c        2022-04-10 18:09:03.075959743 +0100
--- src/search.c        2022-04-16 12:27:13.228168375 +0100
***************
*** 4648,4666 ****
        char_u          *key,
        callback_T      *item_cb,
        int             retmatchpos,
!       list_T          *fmatchlist)
  {
      long      len;
      fuzzyItem_T       *ptrs;
      listitem_T        *li;
      long      i = 0;
!     int               found_match = FALSE;
      int_u     matches[MAX_FUZZY_MATCHES];
  
      len = list_len(items);
      if (len == 0)
        return;
  
      ptrs = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
      if (ptrs == NULL)
        return;
--- 4648,4668 ----
        char_u          *key,
        callback_T      *item_cb,
        int             retmatchpos,
!       list_T          *fmatchlist,
!       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;
***************
*** 4675,4680 ****
--- 4677,4691 ----
        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
***************
*** 4736,4748 ****
                }
            }
            ptrs[i].score = score;
!           found_match = TRUE;
        }
        ++i;
        clear_tv(&rettv);
      }
  
!     if (found_match)
      {
        list_T          *l;
  
--- 4747,4759 ----
                }
            }
            ptrs[i].score = score;
!           ++found_match;
        }
        ++i;
        clear_tv(&rettv);
      }
  
!     if (found_match > 0)
      {
        list_T          *l;
  
***************
*** 4822,4827 ****
--- 4833,4839 ----
      char_u    *key = NULL;
      int               ret;
      int               matchseq = FALSE;
+     long      max_matches = 0;
  
      if (in_vim9script()
            && (check_for_list_arg(argvars, 0) == FAIL
***************
*** 4879,4884 ****
--- 4891,4906 ----
                return;
            }
        }
+       else if ((di = dict_find(d, (char_u *)"limit", -1)) != NULL)
+       {
+           if (di->di_tv.v_type != VAR_NUMBER)
+           {
+               semsg(_(e_invalid_argument_str), tv_get_string(&di->di_tv));
+               return;
+           }
+           max_matches = (long)tv_get_number_chk(&di->di_tv, NULL);
+       }
+ 
        if (dict_has_key(d, "matchseq"))
            matchseq = TRUE;
      }
***************
*** 4913,4919 ****
      }
  
      fuzzy_match_in_list(argvars[0].vval.v_list, tv_get_string(&argvars[1]),
!           matchseq, key, &cb, retmatchpos, rettv->vval.v_list);
  
  done:
      free_callback(&cb);
--- 4935,4941 ----
      }
  
      fuzzy_match_in_list(argvars[0].vval.v_list, tv_get_string(&argvars[1]),
!           matchseq, key, &cb, retmatchpos, rettv->vval.v_list, max_matches);
  
  done:
      free_callback(&cb);
*** ../vim-8.2.4759/src/testdir/test_matchfuzzy.vim     2021-01-02 
17:31:10.887220293 +0000
--- src/testdir/test_matchfuzzy.vim     2022-04-16 12:16:45.818897317 +0100
***************
*** 230,233 ****
--- 230,245 ----
    call assert_equal([['xффйд'], [[2, 3, 4]], [168]], matchfuzzypos(['xффйд'], 
'фйд'))
  endfunc
  
+ " Test for matchfuzzy() with limit
+ func Test_matchfuzzy_limit()
+   let x = ['1', '2', '3', '2']
+   call assert_equal(['2', '2'], x->matchfuzzy('2'))
+   call assert_equal(['2', '2'], x->matchfuzzy('2', #{}))
+   call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 0}))
+   call assert_equal(['2'], x->matchfuzzy('2', #{limit: 1}))
+   call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 2}))
+   call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 3}))
+   call assert_fails("call matchfuzzy(x, '2', #{limit: '2'})", 'E475:')
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4759/src/version.c       2022-04-16 12:03:34.176519007 +0100
--- src/version.c       2022-04-16 12:18:53.874671915 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4760,
  /**/

-- 
The process for understanding customers primarily involves sitting around with
other marketing people and talking about what you would to if you were dumb
enough to be a customer.
                                (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/20220416113623.CA42C1C05DA%40moolenaar.net.

Raspunde prin e-mail lui