You could try the following code:
let s:option_values = {'foldmethod' : ['manual', 'indent', 'expr', 'marker', 'syntax'],
\ 'bufhidden' : ['hide', 'unload', 'delete', 'wipe'],
\ 'virtualedit' : ['block', 'insert', 'all', 'onemore'] ,}
set wildcharm=<c-z>
cnoremap <expr> <tab>
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
\ '<c-z>' :
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
function! s:SetComplete(A, L, P) abort
let option = matchstr(a:A, '^.*\ze=')
if !has_key(s:option_values, option)
return
endif
let candidates = copy(s:option_values[option])
call map(candidates, 'option . "=" . v:val')
return filter(candidates, 'v:val =~ "^" . a:A')
endfunction
It first defines a dictionary s:option_values
whose purpose is to contain your options (as its keys) and their values (as its values which are lists). Here, as an example, 3 options + values are stored:
'foldmethod'
, 'bufhidden'
, 'virtualedit'
.
set wildcharm=<c-z>
This line sets the 'wildcharm'
option and tells Vim that if it sees <c-z>
in a mapping it must activate the wildmenu. Without setting this option, if you write <tab>
in a mapping, it will simply insert a literal tab character.
cnoremap <expr> <tab>
Begin the definition of a mapping which will type the evaluation of an expression whenever you hit <tab>
on the command-line.
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
The mapping tests if the command-line matches the pattern ^\s*set\s\+\w\+=
, which is a line following the form set option=
, or if the wildmenu is active.
\ '<c-z>' :
If the previous test succeeds, the mapping activates the wildmenu.
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
Otherwise, it replaces the system command :set
with the custom command :Set
, and activates the wildmenu.
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
Define the custom command :Set
which does the same thing as :set
, except it can use a custom completion function whose name is here s:SetComplete()
.
function! s:SetComplete(A, L, P) abort
Begin the definition of the custom completion function.
It must return suggestions/candidates through a list.
The :Set
command will automatically send 3 arguments to it:
- the leading portion of the argument currently being completed on (i.e.
option=...
)
- the entire command line
- the cursor position in it
See :h :command-completion-customlist
for more information.
let option = matchstr(a:A, '^.*\ze=')
Extract the name of the option from the argument being completed on.
if !has_key(s:option_values, option)
return
endif
Check whether option
is in your dictionary. If it's not, the function doesn't return anything.
let candidates = copy(s:option_values[option])
Get a copy of the list of values that the option can take from your dictionary.
call map(candidates, 'option . "=" . v:val')
For each value in the list candidates
, prepend the string option=
(where option
will be evaluated).
return filter(candidates, 'v:val =~ "^" . a:A')
Remove the items from candidates
whose beginning don't match the argument being completed on, and return the result.