patch 8.2.4765: function matchfuzzy() sorts too many items
Problem: Function matchfuzzy() sorts too many items.
Solution: Only put matches in the array. (Yegappan Lakshmanan,
closes #10208)
This commit is contained in:
committed by
Bram Moolenaar
parent
d2edee5cf3
commit
047a7019b2
83
src/search.c
83
src/search.c
@ -4642,7 +4642,7 @@ fuzzy_match_item_compare(const void *s1, const void *s2)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fuzzy_match_in_list(
|
fuzzy_match_in_list(
|
||||||
list_T *items,
|
list_T *l,
|
||||||
char_u *str,
|
char_u *str,
|
||||||
int matchseq,
|
int matchseq,
|
||||||
char_u *key,
|
char_u *key,
|
||||||
@ -4652,39 +4652,31 @@ fuzzy_match_in_list(
|
|||||||
long max_matches)
|
long max_matches)
|
||||||
{
|
{
|
||||||
long len;
|
long len;
|
||||||
fuzzyItem_T *ptrs;
|
fuzzyItem_T *items;
|
||||||
listitem_T *li;
|
listitem_T *li;
|
||||||
long i = 0;
|
long i = 0;
|
||||||
long found_match = 0;
|
long match_count = 0;
|
||||||
int_u matches[MAX_FUZZY_MATCHES];
|
int_u matches[MAX_FUZZY_MATCHES];
|
||||||
|
|
||||||
len = list_len(items);
|
len = list_len(l);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
if (max_matches > 0 && len > max_matches)
|
||||||
|
len = max_matches;
|
||||||
|
|
||||||
// TODO: when using a limit use that instead of "len"
|
items = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
|
||||||
ptrs = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
|
if (items == NULL)
|
||||||
if (ptrs == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// For all the string items in items, get the fuzzy matching score
|
// For all the string items in items, get the fuzzy matching score
|
||||||
FOR_ALL_LIST_ITEMS(items, li)
|
FOR_ALL_LIST_ITEMS(l, li)
|
||||||
{
|
{
|
||||||
int score;
|
int score;
|
||||||
char_u *itemstr;
|
char_u *itemstr;
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
|
|
||||||
ptrs[i].idx = i;
|
if (max_matches > 0 && match_count >= max_matches)
|
||||||
ptrs[i].item = li;
|
break;
|
||||||
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;
|
itemstr = NULL;
|
||||||
rettv.v_type = VAR_UNKNOWN;
|
rettv.v_type = VAR_UNKNOWN;
|
||||||
@ -4717,8 +4709,12 @@ fuzzy_match_in_list(
|
|||||||
|
|
||||||
if (itemstr != NULL
|
if (itemstr != NULL
|
||||||
&& fuzzy_match(itemstr, str, matchseq, &score, matches,
|
&& fuzzy_match(itemstr, str, matchseq, &score, matches,
|
||||||
sizeof(matches) / sizeof(matches[0])))
|
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
|
// Copy the list of matching positions in itemstr to a list, if
|
||||||
// 'retmatchpos' is set.
|
// 'retmatchpos' is set.
|
||||||
if (retmatchpos)
|
if (retmatchpos)
|
||||||
@ -4726,8 +4722,8 @@ fuzzy_match_in_list(
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
ptrs[i].lmatchpos = list_alloc();
|
items[match_count].lmatchpos = list_alloc();
|
||||||
if (ptrs[i].lmatchpos == NULL)
|
if (items[match_count].lmatchpos == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
p = str;
|
p = str;
|
||||||
@ -4735,7 +4731,7 @@ fuzzy_match_in_list(
|
|||||||
{
|
{
|
||||||
if (!VIM_ISWHITE(PTR2CHAR(p)))
|
if (!VIM_ISWHITE(PTR2CHAR(p)))
|
||||||
{
|
{
|
||||||
if (list_append_number(ptrs[i].lmatchpos,
|
if (list_append_number(items[match_count].lmatchpos,
|
||||||
matches[j]) == FAIL)
|
matches[j]) == FAIL)
|
||||||
goto done;
|
goto done;
|
||||||
j++;
|
j++;
|
||||||
@ -4746,19 +4742,17 @@ fuzzy_match_in_list(
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptrs[i].score = score;
|
++match_count;
|
||||||
++found_match;
|
|
||||||
}
|
}
|
||||||
++i;
|
|
||||||
clear_tv(&rettv);
|
clear_tv(&rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_match > 0)
|
if (match_count > 0)
|
||||||
{
|
{
|
||||||
list_T *l;
|
list_T *retlist;
|
||||||
|
|
||||||
// Sort the list by the descending order of the match score
|
// Sort the list by the descending order of the match score
|
||||||
qsort((void *)ptrs, (size_t)len, sizeof(fuzzyItem_T),
|
qsort((void *)items, (size_t)match_count, sizeof(fuzzyItem_T),
|
||||||
fuzzy_match_item_compare);
|
fuzzy_match_item_compare);
|
||||||
|
|
||||||
// For matchfuzzy(), return a list of matched strings.
|
// For matchfuzzy(), return a list of matched strings.
|
||||||
@ -4773,17 +4767,17 @@ fuzzy_match_in_list(
|
|||||||
li = list_find(fmatchlist, 0);
|
li = list_find(fmatchlist, 0);
|
||||||
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
l = li->li_tv.vval.v_list;
|
retlist = li->li_tv.vval.v_list;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
l = fmatchlist;
|
retlist = fmatchlist;
|
||||||
|
|
||||||
// Copy the matching strings with a valid score to the return list
|
// Copy the matching strings with a valid score to the return list
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < match_count; i++)
|
||||||
{
|
{
|
||||||
if (ptrs[i].score == SCORE_NONE)
|
if (items[i].score == SCORE_NONE)
|
||||||
break;
|
break;
|
||||||
list_append_tv(l, &ptrs[i].item->li_tv);
|
list_append_tv(retlist, &items[i].item->li_tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// next copy the list of matching positions
|
// next copy the list of matching positions
|
||||||
@ -4792,14 +4786,15 @@ fuzzy_match_in_list(
|
|||||||
li = list_find(fmatchlist, -2);
|
li = list_find(fmatchlist, -2);
|
||||||
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
l = li->li_tv.vval.v_list;
|
retlist = li->li_tv.vval.v_list;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < match_count; i++)
|
||||||
{
|
{
|
||||||
if (ptrs[i].score == SCORE_NONE)
|
if (items[i].score == SCORE_NONE)
|
||||||
break;
|
break;
|
||||||
if (ptrs[i].lmatchpos != NULL
|
if (items[i].lmatchpos != NULL
|
||||||
&& list_append_list(l, ptrs[i].lmatchpos) == FAIL)
|
&& list_append_list(retlist, items[i].lmatchpos)
|
||||||
|
== FAIL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4807,19 +4802,19 @@ fuzzy_match_in_list(
|
|||||||
li = list_find(fmatchlist, -1);
|
li = list_find(fmatchlist, -1);
|
||||||
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
if (li == NULL || li->li_tv.vval.v_list == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
l = li->li_tv.vval.v_list;
|
retlist = li->li_tv.vval.v_list;
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < match_count; i++)
|
||||||
{
|
{
|
||||||
if (ptrs[i].score == SCORE_NONE)
|
if (items[i].score == SCORE_NONE)
|
||||||
break;
|
break;
|
||||||
if (list_append_number(l, ptrs[i].score) == FAIL)
|
if (list_append_number(retlist, items[i].score) == FAIL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
vim_free(ptrs);
|
vim_free(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4765,
|
||||||
/**/
|
/**/
|
||||||
4764,
|
4764,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user