Wie erstelle ich meine eigene Liste der automatischen Vervollständigung für bestimmte Dateitypen?
Zum Beispiel möchte ich, dass CSS und HTML automatisch aus der Liste der CSS-Klassen in FontAwesome vervollständigt werden .
Wie erstelle ich meine eigene Liste der automatischen Vervollständigung für bestimmte Dateitypen?
Zum Beispiel möchte ich, dass CSS und HTML automatisch aus der Liste der CSS-Klassen in FontAwesome vervollständigt werden .
Antworten:
Die Vervollständigung des Wörterbuchs wäre eine kostengünstige und nicht aufdringliche Lösung:
speichere fontawesome.txt irgendwo auf deinem Rechner,
Setze dies ein after/ftplugin/css.vim
(erstelle die Datei, wenn sie nicht existiert):
setlocal complete+=k
setlocal dictionary+=/path/to/fontawesome.txt
setlocal iskeyword+=-
Starten Sie eine neue Sitzung oder verwenden Sie :e
einen CSS-Puffer, um die obige Datei zwangsweise als Quelle zu verwenden.
Drücken Sie <C-n>
oder <C-p>
im Einfügemodus.
genießen!
Referenz:
:help ins-completion
:help 'complete'
:help 'dictionary'
:help 'iskeyword'
EDIT Dank romainl Kommentar Ich habe meine Antwort bearbeitet zu zeigen , wie eine benutzerdefinierte Vervollständigungsfunktion zu erstellen. In der vorherigen Version habe ich die eingebaute Omni-Vervollständigung überschrieben, was nicht gut war, da der Benutzer die Standard-Vervollständigung verloren hätte, die ziemlich mächtig ist.
Eine Vimscript-Lösung
Eine Lösung ist die Verwendung von Vimscript und die Tatsache, dass Sie mit Vim eine benutzerdefinierte Vervollständigungsfunktion erstellen können.
Der Vorteil dieser Lösung ist, dass Sie kein zusätzliches Plugin benötigen. Sie können einfach eine benutzerdefinierte Vervollständigungsfunktion erstellen und die integrierte Vervollständigungsfunktion verwenden.
Ich werde Ihr Beispiel der fontAwesome-Klassen in css
Dateien verwenden:
Erstellen Sie die Datei ~/.vim/autoload/csscomplete.vim
und fügen Sie die folgenden Zeilen ein:
let s:matches=".fa-lg .fa-2x .fa-3x .fa-4x .fa-5x .fa-fw .fa-ul .fa-ul .fa-li .fa-li.fa-lg .fa-border .fa-pull-left .fa-pull-right .fa.fa-pull-left"
function! csscomplete#CompleteFA(findstart, base)
if a:findstart
" locate the start of the word
let line = getline('.')
let start = col('.') - 1
while start > 0 && (line[start - 1] =~ '\a' || line[start - 1] =~ '.' || line[start - 1] =~ '-')
let start -= 1
endwhile
return start
else
" find classes matching "a:base"
let res = []
for m in split(s:matches)
if m =~ '^' . a:base
call add(res, m)
endif
endfor
return res
endif
endfun
Dann erstelle die Datei ~/.vim/after/ftplugin/css.vim
und füge die folgende Zeile ein:
setlocal completefunc=csscomplete#CompleteFA
Dann können Sie mit Ihre benutzerdefinierte Vervollständigungsfunktion auslösen <C-x><C-u>
. Es wird versucht, eine Übereinstimmung mit dem zuletzt eingegebenen Wort zu finden.
Im Screenshot habe ich getippt .fa-l
und dann die Funktion ausgelöst mit <C-x><C-u>
:
Wie funktioniert es?
Hier sind zunächst einige relevante Dokumentationsthemen:
Eine gute Antwort auf die Organisation von Dateien.
Wenn Sie eine benutzerdefinierte Vervollständigung für einen bestimmten Dateityp erstellen möchten, müssen Sie diese in die Datei einfügen $HOME/.vim/autoload/{FILETYPE}complete.vim
.
Dann müssen Sie in dieser Datei Ihre Vervollständigungsfunktion erstellen, die zweimal aufgerufen wird:
Beim ersten Aufruf ist das erste Argument die aktuelle Position des Cursors und die Funktion bestimmt das zu vervollständigende Wort. In meiner Funktion I 3 Vergleiche das Wort vollständig zu erhalten , weil die Klasse kann aus Buchstaben besteht, .
und -
(ich glaube , es ist möglich , diese Anpassung zu verbessern , aber ich bin wirklich schlecht mit regex)
Beim zweiten Aufruf ist das zweite Argument das zu vergleichende Wort, und die Funktion vergleicht es mit der Liste der möglichen Klassen, die mit 1 übereinstimmen . Hier sehen Sie , dass ich ein Wörterbuch zurück , die den Abschluss Menü bevölkern, aber wenn Sie die Dokumentation lesen werde sehen Sie , dass Sie ein viel komplexeres Wörterbuch erstellen anpassen noch das Verhalten Ihrer Funktion.
Sie müssen Vim auch mitteilen, dass für diese Art von Datei die von mir erstellte vollständige Funktion verwendet werden soll. Dazu müssen Sie completefunc
den Namen der von Ihnen erstellten Funktion (hier csscomplete#CompleteFA
) angeben und diese Einstellung in der Datei vornehmen $HOME/.vim/after/ftplugin/{FILETYPE}.vim
.
1 In meiner Funktion s:matches
enthält die Variable alle möglichen Übereinstimmungen. Hier habe ich nur einige Vorschläge für die Lesbarkeit, aber Sie können alle von FontAwesome angebotenen Klassen einfügen (Sie finden die vollständige Liste in dieser von romainl erstellten Datei).
Was ist, wenn ich Vimscript nicht mag?
Eine Möglichkeit besteht darin, das Plugin YoucompleteMe zu verwenden, das eine API zum Spielen mit dem Vervollständigungsmenü bietet. Sie können eine Python-Funktion erstellen, die den passenden Job ausführt und die API verwendet, um die Vim-Oberfläche zu füllen. Weitere Details hier .
Manchmal möchten Sie eine benutzerdefinierte automatische Vervollständigung, die die integrierten oder benutzerdefinierten automatischen Vervollständigungen überhaupt nicht beeinträchtigt. Dies ist besonders nützlich für Skripte oder Plugins, die für eine Vielzahl von Dateitypen geeignet sind.
Dies kann mit der complete()
Funktion und einem einfachen Wrapper relativ einfach durchgeführt werden
. Der größte Teil der Prozedur ist derselbe wie in
:help complete-functions
und Statoxs Antwort beschrieben, außer dass Sie Ihre eigenen Zuordnungen definieren und sich complete()
selbst aufrufen müssen, anstatt einen Wert zurückzugeben.
Hier ist ein einfaches Beispiel, die Kommentare sollten erklären, wie es funktioniert.
" Map <C-x><C-m> for our custom completion
inoremap <C-x><C-m> <C-r>=MyComplete()<CR>
" Make subsequent <C-m> presses after <C-x><C-m> go to the next entry (just like
" other <C-x>* mappings)
inoremap <expr> <C-m> pumvisible() ? "\<C-n>" : "\<C-m>"
" Complete function for addresses; we match the name & address
fun! MyComplete()
" The data. In this example it's static, but you could read it from a file,
" get it from a command, etc.
let l:data = [
\ ["Elmo the Elk", "daring@brave.com"],
\ ["Eek the Cat", "doesnthurt@help.com"]
\ ]
" Locate the start of the word and store the text we want to match in l:base
let l:line = getline('.')
let l:start = col('.') - 1
while l:start > 0 && l:line[l:start - 1] =~ '\a'
let l:start -= 1
endwhile
let l:base = l:line[l:start : col('.')-1]
" Record what matches − we pass this to complete() later
let l:res = []
" Find matches
for m in l:data
" Check if it matches what we're trying to complete; in this case we
" want to match against the start of both the first and second list
" entries (i.e. the name and email address)
if l:m[0] !~? '^' . l:base && l:m[1] !~? '^' . l:base
" Doesn't match
continue
endif
" It matches! See :help complete() for the full docs on the key names
" for this dict.
call add(l:res, {
\ 'icase': 1,
\ 'word': l:m[0] . ' <' . l:m[1] . '>, ',
\ 'abbr': l:m[0],
\ 'menu': l:m[1],
\ 'info': len(l:m) > 2 ? join(l:m[2:], "\n") : '',
\ })
endfor
" Now call the complete() function
call complete(l:start + 1, l:res)
return ''
endfun
:help i_ctrl-x_ctrl-u
.