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_values
có 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 :set
bằng lệnh tùy chỉnh :Set
và 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 :Set
thự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 :Set
lệ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 option
có 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 option
sẽ được đánh giá).
return filter(candidates, 'v:val =~ "^" . a:A')
Xóa các mục khỏi candidates
phần bắt đầu không khớp với đối số đang được hoàn thành và trả về kết quả.