patch 9.1.1833: completion: fuzzy candidates are not sorted
Problem: completion: fuzzy candidates are not sorted
(ddad431)
Solution: Always sort fuzzy candidates (Girish Palya)
fixes: #18488
closes: #18497
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
a51c53722c
commit
10aa04e3d4
@ -1560,24 +1560,41 @@ theend:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set fuzzy score.
|
* Set fuzzy score for completion matches.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
set_fuzzy_score(void)
|
set_fuzzy_score(void)
|
||||||
{
|
{
|
||||||
compl_T *compl;
|
compl_T *compl;
|
||||||
|
char_u *pattern;
|
||||||
|
int use_leader;
|
||||||
|
|
||||||
if (!compl_first_match
|
if (compl_first_match == NULL)
|
||||||
|| compl_leader.string == NULL || compl_leader.length == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void)get_leader_for_startcol(NULL, TRUE); // Clear the cache
|
/* Determine the pattern to match against */
|
||||||
|
use_leader = (compl_leader.string != NULL && compl_leader.length > 0);
|
||||||
|
if (!use_leader)
|
||||||
|
{
|
||||||
|
if (compl_orig_text.string == NULL || compl_orig_text.length == 0)
|
||||||
|
return;
|
||||||
|
pattern = compl_orig_text.string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear the leader cache once before the loop */
|
||||||
|
(void)get_leader_for_startcol(NULL, TRUE);
|
||||||
|
pattern = NULL; /* Will be computed per-completion */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Score all completion matches */
|
||||||
compl = compl_first_match;
|
compl = compl_first_match;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
compl->cp_score = fuzzy_match_str(compl->cp_str.string,
|
if (use_leader)
|
||||||
get_leader_for_startcol(compl, TRUE)->string);
|
pattern = get_leader_for_startcol(compl, TRUE)->string;
|
||||||
|
|
||||||
|
compl->cp_score = fuzzy_match_str(compl->cp_str.string, pattern);
|
||||||
compl = compl->cp_next;
|
compl = compl->cp_next;
|
||||||
} while (compl != NULL && !is_first_match(compl));
|
} while (compl != NULL && !is_first_match(compl));
|
||||||
}
|
}
|
||||||
@ -2471,6 +2488,30 @@ ins_compl_has_autocomplete(void)
|
|||||||
return curbuf->b_p_ac >= 0 ? curbuf->b_p_ac : p_ac;
|
return curbuf->b_p_ac >= 0 ? curbuf->b_p_ac : p_ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cacluate fuzzy score and sort completion matches unless sorting is disabled.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ins_compl_fuzzy_sort(void)
|
||||||
|
{
|
||||||
|
int cur_cot_flags = get_cot_flags();
|
||||||
|
|
||||||
|
// set the fuzzy score in cp_score
|
||||||
|
set_fuzzy_score();
|
||||||
|
// Sort the matches linked list based on fuzzy score
|
||||||
|
if (!(cur_cot_flags & COT_NOSORT))
|
||||||
|
{
|
||||||
|
sort_compl_match_list(cp_compare_fuzzy);
|
||||||
|
if ((cur_cot_flags & (COT_NOINSERT | COT_NOSELECT)) == COT_NOINSERT
|
||||||
|
&& compl_first_match)
|
||||||
|
{
|
||||||
|
compl_shown_match = compl_first_match;
|
||||||
|
if (compl_shows_dir_forward() && !compl_autocomplete)
|
||||||
|
compl_shown_match = compl_first_match->cp_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after changing "compl_leader".
|
* Called after changing "compl_leader".
|
||||||
* Show the popup menu with a different set of matches.
|
* Show the popup menu with a different set of matches.
|
||||||
@ -2479,7 +2520,6 @@ ins_compl_has_autocomplete(void)
|
|||||||
static void
|
static void
|
||||||
ins_compl_new_leader(void)
|
ins_compl_new_leader(void)
|
||||||
{
|
{
|
||||||
int cur_cot_flags = get_cot_flags();
|
|
||||||
int save_w_wrow = curwin->w_wrow;
|
int save_w_wrow = curwin->w_wrow;
|
||||||
int save_w_leftcol = curwin->w_leftcol;
|
int save_w_leftcol = curwin->w_leftcol;
|
||||||
|
|
||||||
@ -2499,6 +2539,8 @@ ins_compl_new_leader(void)
|
|||||||
ins_compl_set_original_text(compl_leader.string, compl_leader.length);
|
ins_compl_set_original_text(compl_leader.string, compl_leader.length);
|
||||||
if (is_cpt_func_refresh_always())
|
if (is_cpt_func_refresh_always())
|
||||||
cpt_compl_refresh();
|
cpt_compl_refresh();
|
||||||
|
if (get_cot_flags() & COT_FUZZY)
|
||||||
|
ins_compl_fuzzy_sort();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2529,24 +2571,6 @@ ins_compl_new_leader(void)
|
|||||||
compl_restarting = FALSE;
|
compl_restarting = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When 'cot' contains "fuzzy" set the cp_score and maybe sort
|
|
||||||
if (cur_cot_flags & COT_FUZZY)
|
|
||||||
{
|
|
||||||
set_fuzzy_score();
|
|
||||||
// Sort the matches linked list based on fuzzy score
|
|
||||||
if (!(cur_cot_flags & COT_NOSORT))
|
|
||||||
{
|
|
||||||
sort_compl_match_list(cp_compare_fuzzy);
|
|
||||||
if ((cur_cot_flags & (COT_NOINSERT | COT_NOSELECT)) == COT_NOINSERT
|
|
||||||
&& compl_first_match)
|
|
||||||
{
|
|
||||||
compl_shown_match = compl_first_match;
|
|
||||||
if (compl_shows_dir_forward() && !compl_autocomplete)
|
|
||||||
compl_shown_match = compl_first_match->cp_next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compl_enter_selects = !compl_used_match && compl_selected_item != -1;
|
compl_enter_selects = !compl_used_match && compl_selected_item != -1;
|
||||||
|
|
||||||
// Show the popup menu with a different set of matches.
|
// Show the popup menu with a different set of matches.
|
||||||
@ -5677,6 +5701,9 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
if (is_nearest_active() && !ins_compl_has_preinsert())
|
if (is_nearest_active() && !ins_compl_has_preinsert())
|
||||||
sort_compl_match_list(cp_compare_nearest);
|
sort_compl_match_list(cp_compare_nearest);
|
||||||
|
|
||||||
|
if ((get_cot_flags() & COT_FUZZY) && ins_compl_leader_len() > 0)
|
||||||
|
ins_compl_fuzzy_sort();
|
||||||
|
|
||||||
return match_count;
|
return match_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6436,7 +6463,9 @@ ins_compl_check_keys(int frequency, int in_compl_func)
|
|||||||
check_elapsed_time();
|
check_elapsed_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compl_pending && !got_int && !(cot_flags & COT_NOINSERT)
|
if (compl_pending
|
||||||
|
&& !got_int
|
||||||
|
&& !(cot_flags & (COT_NOINSERT | COT_FUZZY))
|
||||||
&& (!compl_autocomplete || ins_compl_has_preinsert()))
|
&& (!compl_autocomplete || ins_compl_has_preinsert()))
|
||||||
{
|
{
|
||||||
// Insert the first match immediately and advance compl_shown_match,
|
// Insert the first match immediately and advance compl_shown_match,
|
||||||
|
|||||||
@ -3531,9 +3531,9 @@ func Test_complete_opt_fuzzy()
|
|||||||
|
|
||||||
set cot=menu,fuzzy
|
set cot=menu,fuzzy
|
||||||
call feedkeys("Sblue\<CR>bar\<CR>b\<C-X>\<C-P>\<C-Y>\<ESC>", 'tx')
|
call feedkeys("Sblue\<CR>bar\<CR>b\<C-X>\<C-P>\<C-Y>\<ESC>", 'tx')
|
||||||
call assert_equal('bar', getline('.'))
|
|
||||||
call feedkeys("Sb\<C-X>\<C-N>\<C-Y>\<ESC>", 'tx')
|
|
||||||
call assert_equal('blue', getline('.'))
|
call assert_equal('blue', getline('.'))
|
||||||
|
call feedkeys("Sb\<C-X>\<C-N>\<C-Y>\<ESC>", 'tx')
|
||||||
|
call assert_equal('bar', getline('.'))
|
||||||
call feedkeys("Sb\<C-X>\<C-P>\<C-N>\<C-Y>\<ESC>", 'tx')
|
call feedkeys("Sb\<C-X>\<C-P>\<C-N>\<C-Y>\<ESC>", 'tx')
|
||||||
call assert_equal('b', getline('.'))
|
call assert_equal('b', getline('.'))
|
||||||
|
|
||||||
@ -3558,15 +3558,29 @@ func Test_complete_opt_fuzzy()
|
|||||||
call feedkeys("S\<C-X>\<C-O>c\<C-Y>", 'tx')
|
call feedkeys("S\<C-X>\<C-O>c\<C-Y>", 'tx')
|
||||||
call assert_equal('cp_str', getline('.'))
|
call assert_equal('cp_str', getline('.'))
|
||||||
|
|
||||||
|
" Issue 18488: sort after collection when "fuzzy" (unless "nosort")
|
||||||
|
%d
|
||||||
|
set completeopt&
|
||||||
|
set completeopt+=fuzzy,noselect completefuzzycollect=keyword
|
||||||
|
func! PrintMenuWords()
|
||||||
|
let info = complete_info(["items"])
|
||||||
|
call map(info.items, {_, v -> v.word})
|
||||||
|
return info
|
||||||
|
endfunc
|
||||||
|
call setline(1, ['func1', 'xfunc', 'func2'])
|
||||||
|
call feedkeys("Gof\<C-N>\<C-R>=PrintMenuWords()\<CR>\<Esc>0", 'tx')
|
||||||
|
call assert_equal('f{''items'': [''func1'', ''func2'', ''xfunc'']}', getline('.'))
|
||||||
|
|
||||||
" clean up
|
" clean up
|
||||||
set omnifunc=
|
set omnifunc=
|
||||||
bw!
|
bw!
|
||||||
set complete& completeopt&
|
set complete& completeopt& completefuzzycollect&
|
||||||
autocmd! AAAAA_Group
|
autocmd! AAAAA_Group
|
||||||
augroup! AAAAA_Group
|
augroup! AAAAA_Group
|
||||||
delfunc OnPumChange
|
delfunc OnPumChange
|
||||||
delfunc Omni_test
|
delfunc Omni_test
|
||||||
delfunc Comp
|
delfunc Comp
|
||||||
|
delfunc PrintMenuWords
|
||||||
unlet g:item
|
unlet g:item
|
||||||
unlet g:word
|
unlet g:word
|
||||||
unlet g:abbr
|
unlet g:abbr
|
||||||
@ -4734,18 +4748,6 @@ func Test_nearest_cpt_option()
|
|||||||
call setline(1, ["fo", "foo", "foobar", "foobarbaz"])
|
call setline(1, ["fo", "foo", "foobar", "foobarbaz"])
|
||||||
exe "normal! 2jof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
exe "normal! 2jof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||||
call assert_equal('fo{''matches'': [''foobarbaz'', ''foobar'', ''foo'', ''fo''], ''selected'': -1}', getline(4))
|
call assert_equal('fo{''matches'': [''foobarbaz'', ''foobar'', ''foo'', ''fo''], ''selected'': -1}', getline(4))
|
||||||
|
|
||||||
" No effect if 'fuzzy' is present
|
|
||||||
set completeopt&
|
|
||||||
set completeopt+=fuzzy,nearest
|
|
||||||
%d
|
|
||||||
call setline(1, ["foo", "fo", "foobarbaz", "foobar"])
|
|
||||||
exe "normal! of\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
|
||||||
call assert_equal('fo{''matches'': [''fo'', ''foobarbaz'', ''foobar'', ''foo''], ''selected'': 0}', getline(2))
|
|
||||||
%d
|
|
||||||
call setline(1, ["fo", "foo", "foobar", "foobarbaz"])
|
|
||||||
exe "normal! 2jof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
|
||||||
call assert_equal('foobar{''matches'': [''foobarbaz'', ''fo'', ''foo'', ''foobar''], ''selected'': 3}', getline(4))
|
|
||||||
bw!
|
bw!
|
||||||
|
|
||||||
set completeopt&
|
set completeopt&
|
||||||
|
|||||||
@ -729,6 +729,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 */
|
||||||
|
/**/
|
||||||
|
1833,
|
||||||
/**/
|
/**/
|
||||||
1832,
|
1832,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user