Możesz wypróbować następujący kod:
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
Najpierw definiuje słownik, s:option_values
który ma zawierać twoje opcje (jako klucze) i ich wartości (jako wartości, które są listami). Oto, na przykład, 3 opcje + wartości zapisywane są:
'foldmethod'
, 'bufhidden'
, 'virtualedit'
.
set wildcharm=<c-z>
Ta linia ustawia 'wildcharm'
opcję i mówi Vimowi, że jeśli zobaczy <c-z>
mapowanie, musi aktywować wildmenu. Bez ustawiania tej opcji, jeśli piszesz <tab>
w odwzorowaniu, po prostu wstawi dosłowny znak tabulacji.
cnoremap <expr> <tab>
Rozpocznij definicję odwzorowania, która będzie wpisywać ocenę wyrażenia za każdym razem, gdy naciśniesz <tab>
w wierszu polecenia.
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
Odwzorowanie sprawdza, czy wiersz polecenia pasuje do wzorca ^\s*set\s\+\w\+=
, który jest wierszem po formularzu set option=
, lub czy aktywne jest menu wildmenu.
\ '<c-z>' :
Jeśli poprzedni test się powiedzie, mapowanie aktywuje menu Wildmenu.
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
W przeciwnym razie zastępuje polecenie systemowe :set
niestandardowym poleceniem :Set
i aktywuje wildmenu.
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
Zdefiniuj niestandardowe polecenie, :Set
które robi to samo :set
, z wyjątkiem tego, że może używać niestandardowej funkcji uzupełniania, której nazwa jest tutaj s:SetComplete()
.
function! s:SetComplete(A, L, P) abort
Rozpocznij definicję niestandardowej funkcji uzupełniania.
Musi zwrócić sugestie / kandydatów poprzez listę. Komenda automatycznie wyśle 3 argumenty do niej:
:Set
- wiodąca część argumentu jest obecnie uzupełniana (tj.
option=...
)
- cała linia poleceń
- pozycja kursora w nim
Zobacz :h :command-completion-customlist
po więcej informacji.
let option = matchstr(a:A, '^.*\ze=')
Wyodrębnij nazwę opcji z uzupełnianego argumentu.
if !has_key(s:option_values, option)
return
endif
Sprawdź, czy option
jest w twoim słowniku. Jeśli nie, funkcja nic nie zwraca.
let candidates = copy(s:option_values[option])
Uzyskaj kopię listy wartości, które opcja może pobrać ze słownika.
call map(candidates, 'option . "=" . v:val')
Dla każdej wartości na liście candidates
należy poprzedzić ciąg option=
(gdzie option
zostanie oceniony).
return filter(candidates, 'v:val =~ "^" . a:A')
Usuń elementy, candidates
których początek nie zgadza się z uzupełnianym argumentem, i zwróć wynik.