Automatische Vervollständigung für Optionswerte in der cmdline

10

Ich kann nicht zählen, wie oft ich dies versucht habe:

:set foldmethod=syn^I

Es scheint, dass die Vervollständigung bei Optionswerten nicht funktioniert!

In einigen Fällen handelt es sich bei Optionen um komplexe Zeichenfolgen, bei denen die Vervollständigung möglicherweise keinen Sinn ergibt. (ZB 'comments')

Aber gab es irgendwelche Bemühungen, Wildchar-Vervollständigung für die allgemeinen Anwendungsfälle bereitzustellen?

Wenn nicht, wie könnte ich das obige Beispiel zum Laufen bringen? (Angenommen, ich wollte eine der Saiten vervollständigen ['manual', 'indent', 'expr', 'marker', 'syntax'].)

joeytwiddle
quelle

Antworten:

3

Sie können den folgenden Code ausprobieren:

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

Zunächst wird ein Wörterbuch definiert, s:option_valuesdessen Zweck darin besteht, Ihre Optionen (als Schlüssel) und deren Werte (als Listenwerte) zu enthalten. Hier als Beispiel 3 Optionen + Werte werden gespeichert:
'foldmethod', 'bufhidden', 'virtualedit'.

set wildcharm=<c-z>

Diese Zeile setzt die 'wildcharm'Option und teilt Vim mit, dass <c-z>das Platzmenü aktiviert werden muss , wenn es in einem Mapping angezeigt wird. Wenn Sie <tab>in eine Zuordnung schreiben, ohne diese Option festzulegen, wird einfach ein wörtliches Tabulatorzeichen eingefügt.

cnoremap <expr> <tab>

Beginnen Sie mit der Definition einer Zuordnung, die die Auswertung eines Ausdrucks eingibt, wenn Sie <tab>auf die Befehlszeile klicken.

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

Das Mapping testet, ob die Befehlszeile mit dem Muster übereinstimmt ^\s*set\s\+\w\+=, bei dem es sich um eine Zeile handelt, die dem Formular folgt set option=, oder ob das Platzhaltermenü aktiv ist.

\ '<c-z>' :

Wenn der vorherige Test erfolgreich ist, aktiviert das Mapping das Platzhaltermenü.

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

Andernfalls wird der Systembefehl :setdurch den benutzerdefinierten Befehl ersetzt :Setund das Platzhaltermenü aktiviert.

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

Definieren Sie den benutzerdefinierten Befehl :Set, der dasselbe tut wie :set, außer dass eine benutzerdefinierte Vervollständigungsfunktion verwendet werden kann, deren Name hier steht s:SetComplete().

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

Beginnen Sie mit der Definition der benutzerdefinierten Vervollständigungsfunktion.

Es muss Vorschläge / Kandidaten über eine Liste zurückgeben.
Der :SetBefehl sendet automatisch 3 Argumente an ihn:

  • der führende Teil des Arguments wird derzeit abgeschlossen am (dh option=...)
  • die gesamte Kommandozeile
  • die Cursorposition darin

Siehe :h :command-completion-customlistfür weitere Informationen.

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

Extrahieren Sie den Namen der Option aus dem Argument, das am ausgeführt wird.

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

Überprüfen Sie, ob optiones in Ihrem Wörterbuch ist. Ist dies nicht der Fall, gibt die Funktion nichts zurück.

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

Holen Sie sich eine Kopie der Werteliste, die die Option aus Ihrem Wörterbuch übernehmen kann.

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

candidatesStellen Sie für jeden Wert in der Liste die Zeichenfolge voran option=(wo optionausgewertet wird).

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

Entfernen Sie die Elemente, candidatesderen Anfang nicht mit dem Argument übereinstimmt, das gerade ausgeführt wird, und geben Sie das Ergebnis zurück.

user9433424
quelle
2

AFAIK, wir können eingebauten Befehlen, die sie nicht bereitstellen, keine cmdline-Vervollständigung hinzufügen. Entweder "überschreiben" wir den Befehl mit einem anderen, der die Vervollständigung unterstützt (hier können Sie ihn :Setmit einem Großbuchstaben definieren S), oder wir hacken in den vim-Quellcode, um hinzuzufügen, was fehlt.

Luc Hermitte
quelle