Ви можете спробувати наступний код:
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
Спочатку визначається словник s:option_values, мета якого - містити ваші параметри (як його ключі) та їх значення (як його значення, які є списками). Тут, в якості прикладу, 3 варіанти + значення запам'ятовуються:
'foldmethod', 'bufhidden', 'virtualedit'.
set wildcharm=<c-z>
Цей рядок встановлює 'wildcharm'параметр і повідомляє Vim, що якщо він бачить <c-z>на карті, він повинен активувати дивовижне меню. Без встановлення цієї опції, якщо ви пишете <tab>на карті, він просто вставить буквальний символ вкладки.
cnoremap <expr> <tab>
Почніть визначення карти, яке буде набирати оцінку виразу кожного разу, коли ви натискаєте <tab>на командний рядок.
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
Відображення тестує, чи командний рядок відповідає шаблону ^\s*set\s\+\w\+=, який є рядком, що слідує за формою set option=, або якщо активне меню wild wild.
\ '<c-z>' :
Якщо попередній тест виявився успішним, відображення активує підстановку.
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
В іншому випадку він замінює системну команду :setна власну команду :Setта активує підменю.
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
Визначте користувальницьку команду, :Setяка робить те саме, що і :set, за винятком того, що вона може використовувати функцію завершення, призначена для користувача s:SetComplete().
function! s:SetComplete(A, L, P) abort
Почніть визначення функції користувальницького завершення.
Він повинен повернути пропозиції / кандидатури через список. Команда буде автоматично посилати 3 аргументи йому:
:Set
- провідна частина аргументу, який зараз завершується (тобто
option=...)
- весь командний рядок
- положення курсора в ньому
Див. Для :h :command-completion-customlistотримання додаткової інформації.
let option = matchstr(a:A, '^.*\ze=')
Витягніть назву параметра з аргументу, який завершується.
if !has_key(s:option_values, option)
return
endif
Перевірте, чи optionє у вашому словнику. Якщо це не так, функція нічого не повертає.
let candidates = copy(s:option_values[option])
Отримайте копію списку значень, яку параметр може взяти зі свого словника.
call map(candidates, 'option . "=" . v:val')
Для кожного значення у списку candidatesдодайте рядок option=(де optionбуде оцінено).
return filter(candidates, 'v:val =~ "^" . a:A')
Видаліть елементи candidates, початок яких не відповідає аргументу, який завершено, і поверніть результат.