diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-09-30 08:13:58 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-10-01 20:00:23 +0800 |
commit | f06af5e66981095f3244f67d1587ce7e9853eb4c (patch) | |
tree | bfd07406c05904fc540e08456d7f3e63543a2003 /test | |
parent | 9b3045103f7d56e5ccd0574dcb93e953b72d5f50 (diff) | |
download | rneovim-f06af5e66981095f3244f67d1587ce7e9853eb4c.tar.gz rneovim-f06af5e66981095f3244f67d1587ce7e9853eb4c.tar.bz2 rneovim-f06af5e66981095f3244f67d1587ce7e9853eb4c.zip |
vim-patch:9.0.1958: cannot complete option values
Problem: cannot complete option values
Solution: Add completion functions for several options
Add cmdline tab-completion for setting string options
Add tab-completion for setting string options on the cmdline using
`:set=` (along with `:set+=` and `:set-=`).
The existing tab completion for setting options currently only works
when nothing is typed yet, and it only fills in with the existing value,
e.g. when the user does `:set diffopt=<Tab>` it will be completed to
`set diffopt=internal,filler,closeoff` and nothing else. This isn't too
useful as a user usually wants auto-complete to suggest all the possible
values, such as 'iblank', or 'algorithm:patience'.
For set= and set+=, this adds a new optional callback function for each
option that can be invoked when doing completion. This allows for each
option to have control over how completion works. For example, in
'diffopt', it will suggest the default enumeration, but if `algorithm:`
is selected, it will further suggest different algorithm types like
'meyers' and 'patience'. When using set=, the existing option value will
be filled in as the first choice to preserve the existing behavior. When
using set+= this won't happen as it doesn't make sense.
For flag list options (e.g. 'mouse' and 'guioptions'), completion will
take into account existing typed values (and in the case of set+=, the
existing option value) to make sure it doesn't suggest duplicates.
For set-=, there is a new `ExpandSettingSubtract` function which will
handle flag list and comma-separated options smartly, by only suggesting
values that currently exist in the option.
Note that Vim has some existing code that adds special handling for
'filetype', 'syntax', and misc dir options like 'backupdir'. This change
preserves them as they already work, instead of converting to the new
callback API for each option.
closes: vim/vim#13182
https://github.com/vim/vim/commit/900894b09a95398dfc75599e9f0aa2ea25723384
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/old/testdir/test_options.vim | 296 |
1 files changed, 289 insertions, 7 deletions
diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index c56efe8786..d36e913a30 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -299,11 +299,11 @@ func Test_set_completion() call assert_equal('"set tabstop thesaurus thesaurusfunc', @:) " Expand current value - call feedkeys(":set fileencodings=\<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"set fileencodings=ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes=\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set suffixes=.bak,~,.o,.h,.info,.swp,.obj', @:) - call feedkeys(":set fileencodings:\<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"set fileencodings:ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes:\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set suffixes:.bak,~,.o,.h,.info,.swp,.obj', @:) " Expand key codes. " call feedkeys(":set <H\<C-A>\<C-B>\"\<CR>", 'tx') @@ -364,13 +364,17 @@ func Test_set_completion() call assert_equal("\"set invtabstop=", @:) " Expand options for 'spellsuggest' - call feedkeys(":set spellsuggest=best,file:xyz\<Tab>\<C-B>\"\<CR>", 'xt') - call assert_equal("\"set spellsuggest=best,file:xyz", @:) + call feedkeys(":set spellsuggest=file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal("\"set spellsuggest=file:test_options.vim", @:) + call feedkeys(":set spellsuggest=best,file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal("\"set spellsuggest=best,file:test_options.vim", @:) " Expand value for 'key' " set key=abcd " call feedkeys(":set key=\<Tab>\<C-B>\"\<CR>", 'xt') " call assert_equal('"set key=*****', @:) + " call feedkeys(":set key-=\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set key-=*****', @:) " set key= " Expand values for 'filetype' @@ -386,6 +390,284 @@ func Test_set_completion() call assert_equal('"set syntax=' .. getcompletion('a*', 'syntax')->join(), @:) endfunc +" Test handling of expanding individual string option values +func Test_set_completion_string_values() + " + " Test basic enum string options that have well-defined enum names + " + + " call assert_equal(getcompletion('set display=', 'cmdline'), ['lastline', 'truncate', 'uhex']) + call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + call assert_equal(getcompletion('set display=t', 'cmdline'), ['truncate']) + call assert_equal(getcompletion('set display=*ex*', 'cmdline'), ['uhex']) + + " Test that if a value is set, it will populate the results, but only if + " typed value is empty. + set display=uhex,lastline + " call assert_equal(getcompletion('set display=', 'cmdline'), ['uhex,lastline', 'lastline', 'truncate', 'uhex']) + call assert_equal(['uhex,lastline', 'lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + call assert_equal(getcompletion('set display=u', 'cmdline'), ['uhex']) + " If the set value is part of the enum list, it will show as the first + " result with no duplicate. + set display=uhex + " call assert_equal(getcompletion('set display=', 'cmdline'), ['uhex', 'lastline', 'truncate']) + call assert_equal(['uhex', 'lastline', 'truncate', 'msgsep'], getcompletion('set display=', 'cmdline')) + " If empty value, will just show the normal list without an empty item + set display= + " call assert_equal(getcompletion('set display=', 'cmdline'), ['lastline', 'truncate', 'uhex']) + call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + " Test escaping of the values + " call assert_equal(getcompletion('set fillchars=', 'cmdline')[0], 'vert:\|,fold:-,eob:~,lastline:@') + call assert_equal('vert:\|,foldsep:\|,fold:-', getcompletion('set fillchars=', 'cmdline')[0]) + + " Test comma-separated lists will expand after a comma. + call assert_equal(getcompletion('set display=truncate,*ex*', 'cmdline'), ['uhex']) + " Also test the positioning of the expansion is correct + call feedkeys(":set display=truncate,l\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set display=truncate,lastline', @:) + set display& + + " Test single-value options will not expand after a comma + call assert_equal(getcompletion('set ambw=single,', 'cmdline'), []) + + " Test the other simple options to make sure they have basic auto-complete, + " but don't exhaustively validate their results. + call assert_equal(getcompletion('set ambw=', 'cmdline')[0], 'single') + call assert_match('light\|dark', getcompletion('set bg=', 'cmdline')[1]) + call assert_equal(getcompletion('set backspace=', 'cmdline')[0], 'indent') + call assert_equal(getcompletion('set backupcopy=', 'cmdline')[1], 'yes') + call assert_equal(getcompletion('set belloff=', 'cmdline')[1], 'backspace') + call assert_equal(getcompletion('set briopt=', 'cmdline')[1], 'min:') + if exists('+browsedir') + call assert_equal(getcompletion('set browsedir=', 'cmdline')[1], 'current') + endif + call assert_equal(getcompletion('set bufhidden=', 'cmdline')[1], 'unload') + call assert_equal(getcompletion('set buftype=', 'cmdline')[1], 'nowrite') + call assert_equal(getcompletion('set casemap=', 'cmdline')[1], 'internal') + if exists('+clipboard') + " call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[1]) + call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[0]) + endif + call assert_equal(getcompletion('set complete=', 'cmdline')[1], '.') + call assert_equal(getcompletion('set completeopt=', 'cmdline')[1], 'menu') + if exists('+completeslash') + call assert_equal(getcompletion('set completeslash=', 'cmdline')[1], 'backslash') + endif + if exists('+cryptmethod') + call assert_equal(getcompletion('set cryptmethod=', 'cmdline')[1], 'zip') + endif + if exists('+cursorlineopt') + call assert_equal(getcompletion('set cursorlineopt=', 'cmdline')[1], 'line') + endif + call assert_equal(getcompletion('set debug=', 'cmdline')[1], 'throw') + call assert_equal(getcompletion('set eadirection=', 'cmdline')[1], 'ver') + call assert_equal(getcompletion('set fileformat=', 'cmdline')[2], 'mac') + if exists('+foldclose') + call assert_equal(getcompletion('set foldclose=', 'cmdline')[0], 'all') + endif + if exists('+foldmethod') + call assert_equal(getcompletion('set foldmethod=', 'cmdline')[1], 'expr') + endif + if exists('+foldopen') + call assert_equal(getcompletion('set foldopen=', 'cmdline')[1], 'all') + endif + call assert_equal(getcompletion('set jumpoptions=', 'cmdline')[0], 'stack') + call assert_equal(getcompletion('set keymodel=', 'cmdline')[1], 'stopsel') + call assert_equal(getcompletion('set lispoptions=', 'cmdline')[1], 'expr:1') + call assert_match('popup', getcompletion('set mousemodel=', 'cmdline')[2]) + call assert_equal(getcompletion('set nrformats=', 'cmdline')[1], 'bin') + if exists('+rightleftcmd') + call assert_equal(getcompletion('set rightleftcmd=', 'cmdline')[0], 'search') + endif + call assert_equal(getcompletion('set scrollopt=', 'cmdline')[1], 'ver') + call assert_equal(getcompletion('set selection=', 'cmdline')[1], 'exclusive') + call assert_equal(getcompletion('set selectmode=', 'cmdline')[1], 'key') + if exists('+ssop') + call assert_equal(getcompletion('set ssop=', 'cmdline')[1], 'buffers') + endif + call assert_equal(getcompletion('set showcmdloc=', 'cmdline')[1], 'statusline') + if exists('+signcolumn') + call assert_equal(getcompletion('set signcolumn=', 'cmdline')[1], 'yes') + endif + if exists('+spelloptions') + call assert_equal(getcompletion('set spelloptions=', 'cmdline')[0], 'camel') + endif + if exists('+spellsuggest') + call assert_equal(getcompletion('set spellsuggest+=', 'cmdline')[0], 'best') + endif + call assert_equal(getcompletion('set splitkeep=', 'cmdline')[1], 'screen') + " call assert_equal(getcompletion('set swapsync=', 'cmdline')[1], 'sync') + call assert_equal(getcompletion('set switchbuf=', 'cmdline')[1], 'usetab') + call assert_equal(getcompletion('set tagcase=', 'cmdline')[1], 'ignore') + if exists('+termwintype') + call assert_equal(getcompletion('set termwintype=', 'cmdline')[1], 'conpty') + endif + if exists('+toolbar') + call assert_equal(getcompletion('set toolbar=', 'cmdline')[1], 'text') + endif + if exists('+tbis') + call assert_equal(getcompletion('set tbis=', 'cmdline')[2], 'medium') + endif + if exists('+ttymouse') + set ttymouse= + call assert_equal(getcompletion('set ttymouse=', 'cmdline')[1], 'xterm2') + set ttymouse& + endif + call assert_equal(getcompletion('set virtualedit=', 'cmdline')[1], 'insert') + call assert_equal(getcompletion('set wildmode=', 'cmdline')[1], 'longest') + call assert_equal(getcompletion('set wildmode=list,longest:', 'cmdline')[0], 'full') + call assert_equal(getcompletion('set wildoptions=', 'cmdline')[1], 'tagfile') + if exists('+winaltkeys') + call assert_equal(getcompletion('set winaltkeys=', 'cmdline')[1], 'yes') + endif + + " Other string options that queries the system rather than fixed enum names + call assert_equal(getcompletion('set eventignore=', 'cmdline')[0:1], ['all', 'BufAdd']) + call assert_equal(getcompletion('set fileencodings=', 'cmdline')[1], 'latin1') + " call assert_equal(getcompletion('set printoptions=', 'cmdline')[0], 'top') + " call assert_equal(getcompletion('set wincolor=', 'cmdline')[0], 'SpecialKey') + + call assert_equal(getcompletion('set listchars+=', 'cmdline')[0], 'eol') + call assert_equal(getcompletion('setl listchars+=', 'cmdline')[0], 'eol') + call assert_equal(getcompletion('set fillchars+=', 'cmdline')[0], 'stl') + call assert_equal(getcompletion('setl fillchars+=', 'cmdline')[0], 'stl') + + " + " Unique string options below + " + + " keyprotocol: only auto-complete when after ':' with known protocol types + " call assert_equal(getcompletion('set keyprotocol=', 'cmdline'), [&keyprotocol]) + " call feedkeys(":set keyprotocol+=someterm:m\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set keyprotocol+=someterm:mok2', @:) + " set keyprotocol& + + " previewpopup / completepopup + " call assert_equal(getcompletion('set previewpopup=', 'cmdline')[0], 'height:') + " call assert_equal(getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0], 'EndOfBuffer') + " call feedkeys(":set previewpopup+=border:\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set previewpopup+=border:on', @:) + " call feedkeys(":set completepopup=height:10,align:\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set completepopup=height:10,align:item', @:) + " call assert_equal(getcompletion('set completepopup=bogusname:', 'cmdline'), []) + " set previewpopup& completepopup& + + " diffopt: special handling of algorithm:<alg_list> + call assert_equal(getcompletion('set diffopt+=', 'cmdline')[0], 'filler') + call assert_equal(getcompletion('set diffopt+=iblank,foldcolumn:', 'cmdline'), []) + call assert_equal(getcompletion('set diffopt+=iblank,algorithm:pat*', 'cmdline')[0], 'patience') + + " highlight: special parsing, including auto-completing highlight groups + " after ':' + " call assert_equal(getcompletion('set hl=', 'cmdline')[0:1], [&hl, '8']) + " call assert_equal(getcompletion('set hl+=', 'cmdline')[0], '8') + " call assert_equal(getcompletion('set hl+=8', 'cmdline')[0:2], ['8:', '8b', '8i']) + " call assert_equal(getcompletion('set hl+=8b', 'cmdline')[0], '8bi') + " call assert_equal(getcompletion('set hl+=8:No*ext', 'cmdline')[0], 'NonText') + " If all the display modes are used up we should be suggesting nothing. Make + " a hl typed option with all the modes which will look like '8bi-nrsuc2d=t', + " and make sure nothing is suggested from that. + " let hl_display_modes = join( + " \ filter(map(getcompletion('set hl+=8', 'cmdline'), + " \ {idx, val -> val[1]}), + " \ {idx, val -> val != ':'}), + " \ '') + " call assert_equal(getcompletion('set hl+=8'..hl_display_modes, 'cmdline'), []) + + " + " Test flag lists + " + + " Test set=. Show the original value if nothing is typed after '='. + " Otherwise, the list should avoid showing what's already typed. + set mouse=v + call assert_equal(getcompletion('set mouse=', 'cmdline'), ['v','a','n','i','c','h','r']) + set mouse=nvi + call assert_equal(getcompletion('set mouse=', 'cmdline'), ['nvi','a','n','v','i','c','h','r']) + call assert_equal(getcompletion('set mouse=hn', 'cmdline'), ['a','v','i','c','r']) + + " Test set+=. Never show original value, and it also tries to avoid listing + " flags that's already in the option value. + call assert_equal(getcompletion('set mouse+=', 'cmdline'), ['a','c','h','r']) + call assert_equal(getcompletion('set mouse+=hn', 'cmdline'), ['a','c','r']) + call assert_equal(getcompletion('set mouse+=acrhn', 'cmdline'), []) + + " Test that the position of the expansion is correct (even if there are + " additional values after the current cursor) + call feedkeys(":set mouse=hn\<Left>\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set mouse=han', @:) + set mouse& + + " Test that other flag list options have auto-complete, but don't + " exhaustively validate their results. + if exists('+concealcursor') + call assert_equal(getcompletion('set cocu=', 'cmdline')[0], 'n') + endif + call assert_equal(getcompletion('set cpo=', 'cmdline')[1], 'a') + call assert_equal(getcompletion('set fo=', 'cmdline')[1], 't') + if exists('+guioptions') + call assert_equal(getcompletion('set go=', 'cmdline')[1], '!') + endif + call assert_equal(getcompletion('set shortmess=', 'cmdline')[1], 'r') + call assert_equal(getcompletion('set whichwrap=', 'cmdline')[1], 'b') + + " + "Test set-= + " + + " Normal single-value option just shows the existing value + set ambiwidth=double + call assert_equal(getcompletion('set ambw-=', 'cmdline'), ['double']) + set ambiwidth& + + " Works on numbers and term options as well + call assert_equal(getcompletion('set laststatus-=', 'cmdline'), [string(&laststatus)]) + set t_Ce=testCe + " call assert_equal(getcompletion('set t_Ce-=', 'cmdline'), ['testCe']) + set t_Ce& + + " Comma-separated lists should present each option + set diffopt=context:123,,,,,iblank,iwhiteall + call assert_equal(getcompletion('set diffopt-=', 'cmdline'), ['context:123', 'iblank', 'iwhiteall']) + call assert_equal(getcompletion('set diffopt-=*n*', 'cmdline'), ['context:123', 'iblank']) + call assert_equal(getcompletion('set diffopt-=i', 'cmdline'), ['iblank', 'iwhiteall']) + " Don't present more than one option as it doesn't make sense in set-= + call assert_equal(getcompletion('set diffopt-=iblank,', 'cmdline'), []) + " Test empty option + set diffopt= + call assert_equal(getcompletion('set diffopt-=', 'cmdline'), []) + set diffopt& + + " Test escaping output + call assert_equal(getcompletion('set fillchars-=', 'cmdline')[0], 'vert:\|') + + " Test files with commas in name are being parsed and escaped properly + set path=has\\\ space,file\\,with\\,comma,normal_file + if exists('+completeslash') + call assert_equal(getcompletion('set path-=', 'cmdline'), ['has\\\ space', 'file\,with\,comma', 'normal_file']) + else + call assert_equal(getcompletion('set path-=', 'cmdline'), ['has\\\ space', 'file\\,with\\,comma', 'normal_file']) + endif + set path& + + " Flag list should present orig value, then individual flags + set mouse=v + call assert_equal(getcompletion('set mouse-=', 'cmdline'), ['v']) + set mouse=avn + call assert_equal(getcompletion('set mouse-=', 'cmdline'), ['avn','a','v','n']) + " Don't auto-complete when we have at least one flags already + call assert_equal(getcompletion('set mouse-=n', 'cmdline'), []) + " Test empty option + set mouse= + call assert_equal(getcompletion('set mouse-=', 'cmdline'), []) + set mouse& + + " 'whichwrap' is an odd case where it's both flag list and comma-separated + set ww=b,h + call assert_equal(getcompletion('set ww-=', 'cmdline'), ['b','h']) + set ww& +endfunc + func Test_set_option_errors() call assert_fails('set scroll=-1', 'E49:') call assert_fails('set backupcopy=', 'E474:') @@ -1433,7 +1715,7 @@ func Test_opt_cdhome() set cdhome& endfunc -func Test_set_completion_2() +func Test_set_completion_fuzzy() CheckOption termguicolors " Test default option completion |