Skip to content

Commit 10aa04e

Browse files
girishjichrisbra
authored andcommitted
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 <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent a51c537 commit 10aa04e

File tree

3 files changed

+74
-41
lines changed

3 files changed

+74
-41
lines changed

src/insexpand.c

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,24 +1560,41 @@ get_leader_for_startcol(compl_T *match, int cached)
15601560
}
15611561

15621562
/*
1563-
* Set fuzzy score.
1563+
* Set fuzzy score for completion matches.
15641564
*/
15651565
static void
15661566
set_fuzzy_score(void)
15671567
{
15681568
compl_T *compl;
1569+
char_u *pattern;
1570+
int use_leader;
15691571

1570-
if (!compl_first_match
1571-
|| compl_leader.string == NULL || compl_leader.length == 0)
1572+
if (compl_first_match == NULL)
15721573
return;
15731574

1574-
(void)get_leader_for_startcol(NULL, TRUE); // Clear the cache
1575+
/* Determine the pattern to match against */
1576+
use_leader = (compl_leader.string != NULL && compl_leader.length > 0);
1577+
if (!use_leader)
1578+
{
1579+
if (compl_orig_text.string == NULL || compl_orig_text.length == 0)
1580+
return;
1581+
pattern = compl_orig_text.string;
1582+
}
1583+
else
1584+
{
1585+
/* Clear the leader cache once before the loop */
1586+
(void)get_leader_for_startcol(NULL, TRUE);
1587+
pattern = NULL; /* Will be computed per-completion */
1588+
}
15751589

1590+
/* Score all completion matches */
15761591
compl = compl_first_match;
15771592
do
15781593
{
1579-
compl->cp_score = fuzzy_match_str(compl->cp_str.string,
1580-
get_leader_for_startcol(compl, TRUE)->string);
1594+
if (use_leader)
1595+
pattern = get_leader_for_startcol(compl, TRUE)->string;
1596+
1597+
compl->cp_score = fuzzy_match_str(compl->cp_str.string, pattern);
15811598
compl = compl->cp_next;
15821599
} while (compl != NULL && !is_first_match(compl));
15831600
}
@@ -2471,6 +2488,30 @@ ins_compl_has_autocomplete(void)
24712488
return curbuf->b_p_ac >= 0 ? curbuf->b_p_ac : p_ac;
24722489
}
24732490

2491+
/*
2492+
* Cacluate fuzzy score and sort completion matches unless sorting is disabled.
2493+
*/
2494+
static void
2495+
ins_compl_fuzzy_sort(void)
2496+
{
2497+
int cur_cot_flags = get_cot_flags();
2498+
2499+
// set the fuzzy score in cp_score
2500+
set_fuzzy_score();
2501+
// Sort the matches linked list based on fuzzy score
2502+
if (!(cur_cot_flags & COT_NOSORT))
2503+
{
2504+
sort_compl_match_list(cp_compare_fuzzy);
2505+
if ((cur_cot_flags & (COT_NOINSERT | COT_NOSELECT)) == COT_NOINSERT
2506+
&& compl_first_match)
2507+
{
2508+
compl_shown_match = compl_first_match;
2509+
if (compl_shows_dir_forward() && !compl_autocomplete)
2510+
compl_shown_match = compl_first_match->cp_next;
2511+
}
2512+
}
2513+
}
2514+
24742515
/*
24752516
* Called after changing "compl_leader".
24762517
* Show the popup menu with a different set of matches.
@@ -2479,7 +2520,6 @@ ins_compl_has_autocomplete(void)
24792520
static void
24802521
ins_compl_new_leader(void)
24812522
{
2482-
int cur_cot_flags = get_cot_flags();
24832523
int save_w_wrow = curwin->w_wrow;
24842524
int save_w_leftcol = curwin->w_leftcol;
24852525

@@ -2499,6 +2539,8 @@ ins_compl_new_leader(void)
24992539
ins_compl_set_original_text(compl_leader.string, compl_leader.length);
25002540
if (is_cpt_func_refresh_always())
25012541
cpt_compl_refresh();
2542+
if (get_cot_flags() & COT_FUZZY)
2543+
ins_compl_fuzzy_sort();
25022544
}
25032545
else
25042546
{
@@ -2529,24 +2571,6 @@ ins_compl_new_leader(void)
25292571
compl_restarting = FALSE;
25302572
}
25312573

2532-
// When 'cot' contains "fuzzy" set the cp_score and maybe sort
2533-
if (cur_cot_flags & COT_FUZZY)
2534-
{
2535-
set_fuzzy_score();
2536-
// Sort the matches linked list based on fuzzy score
2537-
if (!(cur_cot_flags & COT_NOSORT))
2538-
{
2539-
sort_compl_match_list(cp_compare_fuzzy);
2540-
if ((cur_cot_flags & (COT_NOINSERT | COT_NOSELECT)) == COT_NOINSERT
2541-
&& compl_first_match)
2542-
{
2543-
compl_shown_match = compl_first_match;
2544-
if (compl_shows_dir_forward() && !compl_autocomplete)
2545-
compl_shown_match = compl_first_match->cp_next;
2546-
}
2547-
}
2548-
}
2549-
25502574
compl_enter_selects = !compl_used_match && compl_selected_item != -1;
25512575

25522576
// Show the popup menu with a different set of matches.
@@ -5677,6 +5701,9 @@ ins_compl_get_exp(pos_T *ini)
56775701
if (is_nearest_active() && !ins_compl_has_preinsert())
56785702
sort_compl_match_list(cp_compare_nearest);
56795703

5704+
if ((get_cot_flags() & COT_FUZZY) && ins_compl_leader_len() > 0)
5705+
ins_compl_fuzzy_sort();
5706+
56805707
return match_count;
56815708
}
56825709

@@ -6436,7 +6463,9 @@ ins_compl_check_keys(int frequency, int in_compl_func)
64366463
check_elapsed_time();
64376464
}
64386465

6439-
if (compl_pending && !got_int && !(cot_flags & COT_NOINSERT)
6466+
if (compl_pending
6467+
&& !got_int
6468+
&& !(cot_flags & (COT_NOINSERT | COT_FUZZY))
64406469
&& (!compl_autocomplete || ins_compl_has_preinsert()))
64416470
{
64426471
// Insert the first match immediately and advance compl_shown_match,

src/testdir/test_ins_complete.vim

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,9 +3531,9 @@ func Test_complete_opt_fuzzy()
35313531

35323532
set cot=menu,fuzzy
35333533
call feedkeys("Sblue\<CR>bar\<CR>b\<C-X>\<C-P>\<C-Y>\<ESC>", 'tx')
3534-
call assert_equal('bar', getline('.'))
3535-
call feedkeys("Sb\<C-X>\<C-N>\<C-Y>\<ESC>", 'tx')
35363534
call assert_equal('blue', getline('.'))
3535+
call feedkeys("Sb\<C-X>\<C-N>\<C-Y>\<ESC>", 'tx')
3536+
call assert_equal('bar', getline('.'))
35373537
call feedkeys("Sb\<C-X>\<C-P>\<C-N>\<C-Y>\<ESC>", 'tx')
35383538
call assert_equal('b', getline('.'))
35393539

@@ -3558,15 +3558,29 @@ func Test_complete_opt_fuzzy()
35583558
call feedkeys("S\<C-X>\<C-O>c\<C-Y>", 'tx')
35593559
call assert_equal('cp_str', getline('.'))
35603560

3561+
" Issue 18488: sort after collection when "fuzzy" (unless "nosort")
3562+
%d
3563+
set completeopt&
3564+
set completeopt+=fuzzy,noselect completefuzzycollect=keyword
3565+
func! PrintMenuWords()
3566+
let info = complete_info(["items"])
3567+
call map(info.items, {_, v -> v.word})
3568+
return info
3569+
endfunc
3570+
call setline(1, ['func1', 'xfunc', 'func2'])
3571+
call feedkeys("Gof\<C-N>\<C-R>=PrintMenuWords()\<CR>\<Esc>0", 'tx')
3572+
call assert_equal('f{''items'': [''func1'', ''func2'', ''xfunc'']}', getline('.'))
3573+
35613574
" clean up
35623575
set omnifunc=
35633576
bw!
3564-
set complete& completeopt&
3577+
set complete& completeopt& completefuzzycollect&
35653578
autocmd! AAAAA_Group
35663579
augroup! AAAAA_Group
35673580
delfunc OnPumChange
35683581
delfunc Omni_test
35693582
delfunc Comp
3583+
delfunc PrintMenuWords
35703584
unlet g:item
35713585
unlet g:word
35723586
unlet g:abbr
@@ -4734,18 +4748,6 @@ func Test_nearest_cpt_option()
47344748
call setline(1, ["fo", "foo", "foobar", "foobarbaz"])
47354749
exe "normal! 2jof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
47364750
call assert_equal('fo{''matches'': [''foobarbaz'', ''foobar'', ''foo'', ''fo''], ''selected'': -1}', getline(4))
4737-
4738-
" No effect if 'fuzzy' is present
4739-
set completeopt&
4740-
set completeopt+=fuzzy,nearest
4741-
%d
4742-
call setline(1, ["foo", "fo", "foobarbaz", "foobar"])
4743-
exe "normal! of\<c-n>\<c-r>=PrintMenuWords()\<cr>"
4744-
call assert_equal('fo{''matches'': [''fo'', ''foobarbaz'', ''foobar'', ''foo''], ''selected'': 0}', getline(2))
4745-
%d
4746-
call setline(1, ["fo", "foo", "foobar", "foobarbaz"])
4747-
exe "normal! 2jof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
4748-
call assert_equal('foobar{''matches'': [''foobarbaz'', ''fo'', ''foo'', ''foobar''], ''selected'': 3}', getline(4))
47494751
bw!
47504752

47514753
set completeopt&

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@ static char *(features[]) =
729729

730730
static int included_patches[] =
731731
{ /* Add new patch number below this line */
732+
/**/
733+
1833,
732734
/**/
733735
1832,
734736
/**/

0 commit comments

Comments
 (0)