Automatyczne uzupełnianie dla wartości opcji na cmdline

10

Nie mogę policzyć, ile razy próbowałem to zrobić:

:set foldmethod=syn^I

Wygląda na to, że zakończenie nie działa na wartości opcji!

W niektórych przypadkach opcje są złożonymi ciągami, w których uzupełnienie może nie mieć sensu. (Np 'comments'.)

Ale czy podjęto jakieś wysiłki w celu zapewnienia uzupełnienia typu wildchar dla typowych przypadków użycia?

Jeśli nie, jak mogę sprawić, by powyższy przykład działał? (Zakładając, że chciałem uzupełnić jeden z ciągów ['manual', 'indent', 'expr', 'marker', 'syntax'].)

joeytwiddle
źródło

Odpowiedzi:

3

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_valuesktó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 :setniestandardowym poleceniem :Seti aktywuje wildmenu.

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

Zdefiniuj niestandardowe polecenie, :Setktó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-customlistpo 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 optionjest 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 candidatesnależy poprzedzić ciąg option=(gdzie optionzostanie oceniony).

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

Usuń elementy, candidatesktórych początek nie zgadza się z uzupełnianym argumentem, i zwróć wynik.

użytkownik9433424
źródło
2

AFAIK, nie możemy dodać cmdline-uzupełniania do wbudowanych poleceń, które tego nie zapewniają. Albo „nadpisujemy” polecenie innym, które będzie obsługiwać ukończenie (tutaj możesz zdefiniować :Setwielką literą S), albo włamujemy się do kodu źródłowego vima, aby dodać to, czego brakuje.

Luc Hermitte
źródło