Penyelesaian otomatis untuk nilai opsi pada cmdline

10

Saya tidak dapat menghitung berapa kali saya mencoba melakukan ini:

:set foldmethod=syn^I

Tampaknya penyelesaian tidak berfungsi pada nilai opsi!

Dalam beberapa kasus opsi adalah string kompleks di mana penyelesaian mungkin tidak masuk akal. (Mis 'comments'.)

Tetapi apakah sudah ada upaya untuk menyediakan penyelesaian wildchar untuk kasus penggunaan umum?

Jika tidak, bagaimana saya bisa membuat contoh di atas berfungsi? (Dengan asumsi saya ingin menyelesaikan ke salah satu string ['manual', 'indent', 'expr', 'marker', 'syntax'].)

joeytwiddle
sumber

Jawaban:

3

Anda dapat mencoba kode berikut:

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

Pertama mendefinisikan kamus s:option_valuesyang tujuannya adalah untuk berisi pilihan Anda (sebagai kuncinya) dan nilainya (sebagai nilainya yang daftar). Di sini, sebagai contoh, 3 pilihan + nilai-nilai yang disimpan:
'foldmethod', 'bufhidden', 'virtualedit'.

set wildcharm=<c-z>

Baris ini menetapkan 'wildcharm'opsi dan memberi tahu Vim bahwa jika dilihat <c-z>dalam pemetaan, ia harus mengaktifkan wildmenu. Tanpa mengatur opsi ini, jika Anda menulis <tab>dalam pemetaan, itu hanya akan memasukkan karakter tab literal.

cnoremap <expr> <tab>

Mulailah definisi pemetaan yang akan mengetik evaluasi ekspresi setiap kali Anda menekan <tab>pada baris perintah.

\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?

Pemetaan akan menguji apakah baris perintah cocok dengan pola ^\s*set\s\+\w\+=, yang merupakan garis yang mengikuti formulir set option=, atau jika wildmenu aktif.

\ '<c-z>' :

Jika tes sebelumnya berhasil, pemetaan mengaktifkan wildmenu.

\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'

Jika tidak, itu menggantikan perintah sistem :setdengan perintah kustom :Set, dan mengaktifkan wildmenu.

command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>

Tetapkan perintah kustom :Setyang melakukan hal yang sama :set, kecuali itu dapat menggunakan fungsi penyelesaian kustom yang namanya ada di sini s:SetComplete().

function! s:SetComplete(A, L, P) abort

Mulai definisi fungsi penyelesaian kustom.

Itu harus mengembalikan saran / kandidat melalui daftar.
The :Setperintah secara otomatis akan mengirimkan 3 argumen untuk itu:

  • bagian utama dari argumen yang saat ini sedang diselesaikan pada (yaitu option=...)
  • seluruh baris perintah
  • posisi kursor di dalamnya

Lihat :h :command-completion-customlistuntuk informasi lebih lanjut.

let option = matchstr(a:A, '^.*\ze=')

Ekstrak nama opsi dari argumen yang sedang diselesaikan.

if !has_key(s:option_values, option)
    return
endif

Periksa apakah optionada di kamus Anda. Jika tidak, fungsi tidak mengembalikan apa pun.

let candidates = copy(s:option_values[option])

Dapatkan salinan daftar nilai yang dapat diambil opsi dari kamus Anda.

call map(candidates, 'option . "=" . v:val')

Untuk setiap nilai dalam daftar candidates, tambahkan string option=(di mana optionakan dievaluasi).

return filter(candidates, 'v:val =~ "^" . a:A')

Hapus item dari candidatesawal yang tidak cocok dengan argumen yang sedang diselesaikan, dan kembalikan hasilnya.

pengguna9433424
sumber
2

AFAIK, kami tidak bisa menambahkan penyelesaian cmdline ke perintah builtin yang tidak menyediakannya. Entah kami "mengganti" perintah dengan perintah lain yang akan mendukung penyelesaian (di sini, Anda dapat mendefinisikan :Setdengan huruf besar S), atau kami meretas kode sumber vim untuk menambahkan apa yang hilang.

Luc Hermitte
sumber