mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
vim-patch:9.1.1311: completion: not possible to limit number of matches
Problem: completion: not possible to limit number of matches
Solution: allow to limit the matches for 'complete' sources by using the
"{flag}^{limit}" notation (Girish Palya)
This change extends the 'complete' option to support limiting the
number of matches returned from individual completion sources.
**Rationale:** In large files, certain sources (such as the current
buffer) can generate an overwhelming number of matches, which may cause
more relevant results from other sources (e.g., LSP or tags) to be
pushed out of view. By specifying per-source match limits, the
completion menu remains balanced and diverse, improving visibility and
relevance of suggestions.
A caret (`^`) followed by a number can be appended to a source flag to
specify the maximum number of matches for that source. For example:
```
:set complete=.^9,w,u,t^5
```
In this configuration:
- The current buffer (`.`) will return up to 9 matches.
- The tag completion (`t`) will return up to 5 matches.
- Other sources (`w`, `u`) are not limited.
This feature is fully backward-compatible and does not affect behavior
when the `^count` suffix is not used.
The caret (`^`) was chosen as the delimiter because it is least likely
to appear in file names.
closes: vim/vim#17087
0ac1eb3555
Cherry-pick test_options.vim change from patch 9.1.1325.
Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
@ -4158,6 +4158,126 @@ func Test_complete_multiline_marks()
|
||||
delfunc Omni_test
|
||||
endfunc
|
||||
|
||||
func Test_complete_match_count()
|
||||
func PrintMenuWords()
|
||||
let info = complete_info(["selected", "matches"])
|
||||
call map(info.matches, {_, v -> v.word})
|
||||
return info
|
||||
endfunc
|
||||
|
||||
new
|
||||
set cpt=.^0,w
|
||||
call setline(1, ["fo", "foo", "foobar", "fobarbaz"])
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo'', ''foo'', ''foobar'', ''fobarbaz''], ''selected'': 0}', getline(5))
|
||||
5d
|
||||
set cpt=.^0,w
|
||||
exe "normal! Gof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fobarbaz{''matches'': [''fo'', ''foo'', ''foobar'', ''fobarbaz''], ''selected'': 3}', getline(5))
|
||||
5d
|
||||
set cpt=.^1,w
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo''], ''selected'': 0}', getline(5))
|
||||
5d
|
||||
" max_matches is ignored for backward search
|
||||
exe "normal! Gof\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fobarbaz{''matches'': [''fo'', ''foo'', ''foobar'', ''fobarbaz''], ''selected'': 3}', getline(5))
|
||||
5d
|
||||
set cpt=.^2,w
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo'', ''foo''], ''selected'': 0}', getline(5))
|
||||
5d
|
||||
set cot=menuone,noselect
|
||||
set cpt=.^1,w
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('f{''matches'': [''fo''], ''selected'': -1}', getline(5))
|
||||
set cot&
|
||||
|
||||
func ComplFunc(findstart, base)
|
||||
if a:findstart
|
||||
return col(".")
|
||||
endif
|
||||
return ["foo1", "foo2", "foo3", "foo4"]
|
||||
endfunc
|
||||
|
||||
%d
|
||||
set completefunc=ComplFunc
|
||||
set cpt=.^1,f^2
|
||||
call setline(1, ["fo", "foo", "foobar", "fobarbaz"])
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 0}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foo1{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 1}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foo2{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 2}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-n>\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('f{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': -1}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 0}', getline(5))
|
||||
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('f{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': -1}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-p>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foo2{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 2}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-p>\<c-p>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foo1{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 1}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-p>\<c-p>\<c-p>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 0}', getline(5))
|
||||
5d
|
||||
exe "normal! Gof\<c-n>\<c-p>\<c-p>\<c-p>\<c-p>\<c-p>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('f{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': -1}', getline(5))
|
||||
|
||||
%d
|
||||
call setline(1, ["foo"])
|
||||
set cpt=fComplFunc^2,.
|
||||
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foo1{''matches'': [''foo1'', ''foo2'', ''foo''], ''selected'': 0}', getline(2))
|
||||
bw!
|
||||
|
||||
" Test refresh:always with max_items
|
||||
let g:CallCount = 0
|
||||
func! CompleteItemsSelect(findstart, base)
|
||||
if a:findstart
|
||||
return col('.') - 1
|
||||
endif
|
||||
let g:CallCount += 1
|
||||
let res = [[], ['foobar'], ['foo1', 'foo2', 'foo3'], ['foo4', 'foo5', 'foo6']]
|
||||
return #{words: res[g:CallCount], refresh: 'always'}
|
||||
endfunc
|
||||
|
||||
new
|
||||
set complete=.,ffunction('CompleteItemsSelect')^2
|
||||
call setline(1, "foobarbar")
|
||||
let g:CallCount = 0
|
||||
exe "normal! Gof\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('foobar{''matches'': [''foobarbar'', ''foobar''], ''selected'': 1}', getline(2))
|
||||
call assert_equal(1, g:CallCount)
|
||||
%d
|
||||
call setline(1, "foobarbar")
|
||||
let g:CallCount = 0
|
||||
exe "normal! Gof\<c-n>\<c-p>o\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('fo{''matches'': [''foobarbar'', ''foo1'', ''foo2''], ''selected'': -1}', getline(2))
|
||||
call assert_equal(2, g:CallCount)
|
||||
%d
|
||||
call setline(1, "foobarbar")
|
||||
let g:CallCount = 0
|
||||
exe "normal! Gof\<c-n>\<c-p>o\<bs>\<c-r>=PrintMenuWords()\<cr>"
|
||||
call assert_equal('f{''matches'': [''foobarbar'', ''foo4'', ''foo5''], ''selected'': -1}', getline(2))
|
||||
call assert_equal(3, g:CallCount)
|
||||
bw!
|
||||
|
||||
set completeopt& complete&
|
||||
delfunc PrintMenuWords
|
||||
endfunc
|
||||
|
||||
func Test_complete_append_selected_match_default()
|
||||
" when typing a normal character during completion,
|
||||
" completion is ended, see
|
||||
|
@ -280,11 +280,20 @@ func Test_complete()
|
||||
call assert_fails('set complete=x', 'E539:')
|
||||
call assert_fails('set complete=..', 'E535:')
|
||||
set complete=.,w,b,u,k,\ s,i,d,],t,U,f,o
|
||||
call assert_fails('set complete=i^-10', 'E535:')
|
||||
call assert_fails('set complete=i^x', 'E535:')
|
||||
call assert_fails('set complete=k^2,t^-1,s^', 'E535:')
|
||||
call assert_fails('set complete=t^-1', 'E535:')
|
||||
call assert_fails('set complete=kfoo^foo2', 'E535:')
|
||||
call assert_fails('set complete=kfoo^', 'E535:')
|
||||
call assert_fails('set complete=.^', 'E535:')
|
||||
set complete=.,w,b,u,k,s,i,d,],t,U,f,o
|
||||
set complete=.
|
||||
set complete=.^10,t^0
|
||||
set complete+=ffuncref('foo'\\,\ [10])
|
||||
set complete=ffuncref('foo'\\,\ [10])
|
||||
set complete=ffuncref('foo'\\,\ [10])^10
|
||||
set complete&
|
||||
set complete+=ffunction('foo'\\,\ [10\\,\ 20])
|
||||
set complete+=ffunction('g:foo'\\,\ [10\\,\ 20])
|
||||
set complete&
|
||||
endfun
|
||||
|
||||
|
Reference in New Issue
Block a user