Bạn có thể thử đoạn mã sau:
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
Trước tiên, nó xác định một từ điển s:option_valuescó mục đích chứa các tùy chọn của bạn (dưới dạng các khóa của nó) và các giá trị của chúng (như các giá trị của nó là danh sách). Ở đây, như một ví dụ, 3 lựa chọn + giá trị được lưu trữ:
'foldmethod', 'bufhidden', 'virtualedit'.
set wildcharm=<c-z>
Dòng này đặt 'wildcharm'tùy chọn và nói với Vim rằng nếu nó nhìn thấy <c-z>trong ánh xạ, nó phải kích hoạt wildmenu. Nếu không thiết lập tùy chọn này, nếu bạn viết <tab>trong ánh xạ, nó sẽ chỉ chèn một ký tự tab theo nghĩa đen.
cnoremap <expr> <tab>
Bắt đầu định nghĩa về ánh xạ sẽ gõ đánh giá biểu thức bất cứ khi nào bạn nhấn <tab>vào dòng lệnh.
\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
Ánh xạ kiểm tra nếu dòng lệnh khớp với mẫu ^\s*set\s\+\w\+=, đó là một dòng theo mẫu set option=hoặc nếu wildmenu đang hoạt động.
\ '<c-z>' :
Nếu thử nghiệm trước đó thành công, ánh xạ kích hoạt wildmenu.
\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'
Mặt khác, nó thay thế lệnh hệ thống :setbằng lệnh tùy chỉnh :Setvà kích hoạt wildmenu.
command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>
Xác định lệnh tùy chỉnh :Setthực hiện tương tự :set, ngoại trừ nó có thể sử dụng chức năng hoàn thành tùy chỉnh có tên ở đây s:SetComplete().
function! s:SetComplete(A, L, P) abort
Bắt đầu định nghĩa của chức năng hoàn thành tùy chỉnh.
Nó phải trả lại đề xuất / ứng cử viên thông qua một danh sách.
Các :Setlệnh sẽ tự động gửi 3 đối số cho nó:
- phần đầu của đối số hiện đang được hoàn thành trên (nghĩa là
option=...)
- toàn bộ dòng lệnh
- vị trí con trỏ trong đó
Xem :h :command-completion-customlistđể biết thêm thông tin.
let option = matchstr(a:A, '^.*\ze=')
Trích xuất tên của tùy chọn từ đối số đang được hoàn thành trên.
if !has_key(s:option_values, option)
return
endif
Kiểm tra xem optioncó trong từ điển của bạn. Nếu không, hàm sẽ không trả về bất cứ thứ gì.
let candidates = copy(s:option_values[option])
Lấy một bản sao của danh sách các giá trị mà tùy chọn có thể lấy từ từ điển của bạn.
call map(candidates, 'option . "=" . v:val')
Đối với mỗi giá trị trong danh sách candidates, hãy thêm chuỗi option=(nơi optionsẽ được đánh giá).
return filter(candidates, 'v:val =~ "^" . a:A')
Xóa các mục khỏi candidatesphần bắt đầu không khớp với đối số đang được hoàn thành và trả về kết quả.