10

I cannot count the number of times I have tried to do this:

:set foldmethod=syn^I

It seems that completion doesn't work on option values!

In some cases options are complex strings where completion might not make sense. (E.g. 'comments'.)

But have there been any efforts to provide wildchar-completion for the common use-cases?

If not, how could I make the example above work? (Assuming I wanted to complete to one of the strings ['manual', 'indent', 'expr', 'marker', 'syntax'].)

3

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.

2

AFAIK, we can't add cmdline-completion to builtin commands that don't provide it. Either we "override" the command with another one that'll support completion (here, you could define :Set with a capital S), or we hack into vim source code to add what is missing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.