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.