Você pode tentar o seguinte código:
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
Primeiro, define um dicionário s:option_values
cujo objetivo é conter suas opções (como chaves) e seus valores (como valores que são listas). Aqui, por exemplo, 3 opções + valores são armazenados:
'foldmethod'
, 'bufhidden'
, 'virtualedit'
.
set wildcharm=<c-z>
Essa linha define a 'wildcharm'
opção e informa ao Vim que, se vir <c-z>
em um mapeamento, deverá ativar o menu curinga. Sem definir essa opção, se você escrever <tab>
em um mapeamento, ele simplesmente inserirá um caractere de tabulação literal.
cnoremap <expr> <tab>
Comece a definição de um mapeamento que digitará a avaliação de uma expressão sempre que você pressionar <tab>
na linha de comando.
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
O mapeamento testa se a linha de comando corresponde ao padrão ^\s*set\s\+\w\+=
, que é uma linha após o formulário set option=
, ou se o menu curinga está ativo.
\ '<c-z>' :
Se o teste anterior for bem-sucedido, o mapeamento ativa o menu curinga.
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
Caso contrário, ele substitui o comando do sistema pelo comando :set
personalizado :Set
e ativa o menu curinga.
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
Defina o comando personalizado :Set
que faz a mesma coisa que :set
, exceto que ele pode usar uma função de conclusão personalizada cujo nome está aqui s:SetComplete()
.
function! s:SetComplete(A, L, P) abort
Comece a definição da função de conclusão customizada.
Ele deve retornar sugestões / candidatos através de uma lista.
O :Set
comando enviará automaticamente 3 argumentos para ele:
- a parte principal do argumento atualmente sendo concluída em (ie
option=...
)
- toda a linha de comando
- a posição do cursor nele
Veja :h :command-completion-customlist
para mais informações.
let option = matchstr(a:A, '^.*\ze=')
Extraia o nome da opção do argumento que está sendo concluído.
if !has_key(s:option_values, option)
return
endif
Verifique se option
está no seu dicionário. Caso contrário, a função não retorna nada.
let candidates = copy(s:option_values[option])
Obtenha uma cópia da lista de valores que a opção pode obter do seu dicionário.
call map(candidates, 'option . "=" . v:val')
Para cada valor na lista candidates
, acrescente a sequência de caracteres option=
(onde option
será avaliada).
return filter(candidates, 'v:val =~ "^" . a:A')
Remova os itens candidates
cujo início não corresponde ao argumento que está sendo concluído e retorne o resultado.