Completamento automatico per i valori delle opzioni sulla cmdline


10

Non riesco a contare il numero di volte in cui ho provato a fare questo:

:set foldmethod=syn^I

Sembra che il completamento non funzioni sui valori delle opzioni!

In alcuni casi le opzioni sono stringhe complesse in cui il completamento potrebbe non avere senso. (Es 'comments'.)

Ma ci sono stati sforzi per fornire il completamento wildchar per i casi d'uso comuni?

In caso contrario, come potrei far funzionare l'esempio sopra? (Supponendo che volessi completare una delle stringhe ['manual', 'indent', 'expr', 'marker', 'syntax'].)

Risposte:


3

Puoi provare il seguente codice:

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

Definisce innanzitutto un dizionario il s:option_valuescui scopo è contenere le opzioni (come le sue chiavi) e i loro valori (come i suoi valori che sono elenchi). Qui, ad esempio, 3 punti + valori sono memorizzati:
'foldmethod', 'bufhidden', 'virtualedit'.

set wildcharm=<c-z>

Questa linea imposta l' 'wildcharm'opzione e dice a Vim che se vede <c-z>in una mappatura deve attivare il menu selvaggio. Senza impostare questa opzione, se si scrive <tab>in una mappatura, verrà semplicemente inserito un carattere di tabulazione letterale.

cnoremap <expr> <tab>

Inizia la definizione di una mappatura che digiterà la valutazione di un'espressione ogni volta che premi <tab>sulla riga di comando.

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

Il mapping verifica se la riga di comando corrisponde al modello ^\s*set\s\+\w\+=, che è una riga che segue il modulo set option=, o se il menu selvaggio è attivo.

\ '<c-z>' :

Se il test precedente ha esito positivo, la mappatura attiva il menu selvaggio.

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

Altrimenti, sostituisce il comando di sistema :setcon il comando personalizzato :Sete attiva il menu selvaggio.

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

Definire il comando personalizzato :Setche fa la stessa cosa :set, tranne che può usare una funzione di completamento personalizzata il cui nome è qui s:SetComplete().

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

Inizia la definizione della funzione di completamento personalizzata.

Deve restituire suggerimenti / candidati attraverso un elenco.
Il :Setcomando invierà automaticamente 3 argomenti:

  • la parte iniziale dell'argomento attualmente in fase di completamento (ovvero option=...)
  • l'intera riga di comando
  • la posizione del cursore al suo interno

Vedi :h :command-completion-customlistper maggiori informazioni.

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

Estrarre il nome dell'opzione dall'argomento in fase di completamento.

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

Controlla se optionè presente nel tuo dizionario. In caso contrario, la funzione non restituisce nulla.

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

Ottieni una copia dell'elenco di valori che l'opzione può prendere dal tuo dizionario.

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

Per ogni valore nell'elenco candidates, anteporre la stringa option=(dove optionverrà valutata).

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

Rimuovere gli elementi il candidatescui inizio non corrisponde all'argomento in fase di completamento e restituire il risultato.


2

AFAIK, non possiamo aggiungere cmdline-completamento ai comandi integrati che non lo forniscono. O "sovrascriviamo" il comando con un altro che supporterà il completamento (qui, potresti definire :Setcon una maiuscola S), oppure hackeriamo il codice sorgente di VIM per aggiungere ciò che manca.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.