patch 9.1.1435: completion: various flaws in fuzzy completion
Problem: completion: various flaws in fuzzy completion
Solution: fix the issues (Girish Palya)
- Remove the brittle `qsort()` on `compl_match_array`.
- Add a stable, non-recursive `mergesort` for the internal doubly
linked list of matches.
- The sort now happens directly on the internal representation (`compl_T`),
preserving sync with external structures and making sorting stable.
- Update fuzzy match logic to enforce `max_matches` limits after
sorting.
- Remove `trim_compl_match_array()`, which is no longer necessary.
- Fixe test failures by correctly setting `selected` index and
maintaining match consistency.
- Introduce `mergesort_list()` in `misc2.c`, which operates generically
over doubly linked lists.
- Remove `pum_score` and `pum_idx` variables
fixes: #17387
closes: #17430
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index 7d67e9f..fcd2e6c 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -3466,7 +3466,7 @@
set cot+=noinsert
call feedkeys("i\<C-R>=CompAnother()\<CR>f", 'tx')
call assert_equal("for", g:abbr)
- call assert_equal(2, g:selected)
+ call assert_equal(0, g:selected)
set cot=menu,menuone,noselect,fuzzy
call feedkeys("i\<C-R>=CompAnother()\<CR>\<C-N>\<C-N>\<C-N>\<C-N>", 'tx')
@@ -3703,7 +3703,7 @@
call assert_equal('hello', getline('.'))
" continue search for new leader after insert common prefix
- exe "normal ohellokate\<CR>h\<C-X>\<C-N>k\<C-y>\<esc>"
+ exe "normal ohellokate\<CR>h\<C-X>\<C-N>k\<C-N>\<C-y>\<esc>"
call assert_equal('hellokate', getline('.'))
bw!
@@ -4110,6 +4110,12 @@
set cpt=.^1,w
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
call assert_equal('f{''matches'': [''fo''], ''selected'': -1}', getline(5))
+ " With non-matching items
+ %d
+ call setline(1, ["free", "freebar", "foo", "fobarbaz"])
+ set cpt=.^2,w
+ exe "normal! Gofo\<c-n>\<c-r>=PrintMenuWords()\<cr>"
+ call assert_equal('fo{''matches'': [''foo'', ''fobarbaz''], ''selected'': -1}', getline(5))
set cot&
func ComplFunc(findstart, base)
@@ -4199,16 +4205,21 @@
bw!
" Test 'fuzzy' with max_items
- " XXX: Cannot use complete_info() since it is broken for 'fuzzy'
new
set completeopt=menu,noselect,fuzzy
set complete=.
call setline(1, ["abcd", "abac", "abdc"])
- execute "normal Goa\<c-n>c\<c-n>"
+ exe "normal! Goa\<c-n>c\<c-r>=PrintMenuWords()\<cr>"
+ call assert_equal('ac{''matches'': [''abac'', ''abcd'', ''abdc''], ''selected'': -1}', getline(4))
+ exe "normal! Sa\<c-n>c\<c-n>\<c-n>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
+ call assert_equal('abac{''matches'': [''abac'', ''abcd'', ''abdc''], ''selected'': 0}', getline(4))
+ execute "normal Sa\<c-n>c\<c-n>"
call assert_equal('abac', getline(4))
execute "normal Sa\<c-n>c\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>"
call assert_equal('abac', getline(4))
set complete=.^1
+ exe "normal! Sa\<c-n>c\<c-n>\<c-n>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
+ call assert_equal('abac{''matches'': [''abac''], ''selected'': 0}', getline(4))
execute "normal Sa\<c-n>c\<c-n>\<c-n>\<c-n>"
call assert_equal('abac', getline(4))
set complete=.^2