Wie kann ich Plugins testen und nur einbinden, wenn sie in .vimrc vorhanden sind?


14

In meinem .vimrcversuche ich ftplugin, einige Befehle zu verwenden und offensichtlich zu verwenden, die sich darauf beziehen, unter der Annahme, dass es erfolgreich geladen wurde. Ich bin jedoch auf ein paar alte Maschinen gestoßen, auf denen das Plugin nicht installiert ist. Kann ich das Laden dieses Plugins irgendwie von Bedingungen abhängig machen filetype onund ähnliche Anweisungen in denselben bedingten Block einfügen?

Ich habe gesehen, dass es Bedingungen für Farbschemata und die Vim-Version gibt, aber ich habe kein Beispiel gesehen, das nach dem Plugin suchen würde (oder es nicht erkannte).

NB: Sei sanft, ich bin ein VimScript-Anfänger.


1
Beachten Sie, dass Plugins nach Ihrem geladen werden ~/.vimrc, sodass Sie die Auswirkungen eines Plugins in Ihrem ~/.vimrcnicht testen können, es sei denn, Sie testen, ob die Plugin-Datei vorhanden ist, oder verschieben den Test, bis Plugins mit einem automatischen Befehl wie z VimEnter.
Garyjohn

@garyjohn: aha, das ist interessant. Weil diese Art der bestehenden Antwort widerspricht. Könnten Sie es als Antwort aufschreiben?
0xC0000022L

Ich habe meine Antwort bearbeitet, um dieses Problem zu beheben.
qqx

Mein Kommentar widersprach nicht der Antwort von qqx; es sollte die Aufmerksamkeit auf einen Punkt lenken, der übersehen werden könnte, wenn man die Antwort von qqx nicht sorgfältig gelesen oder daraus falsche Schlussfolgerungen gezogen hätte. Die Antwort war von Anfang an gut und ist jetzt noch klarer.
Garyjohn

Antworten:


19

Sie können diesen Block in eine Bedingung einschließen, die mithilfe der exists()Funktion überprüft, ob eine vom Plugin definierte Variable, ein Befehl oder eine Funktion als vim bekannt ist.

Hier sind ein paar Bits, die ich in Dateien unter ~ / .vim habe:

" after/plugin/speeddating.vim
if exists(':SpeedDatingFormat')
    SpeedDatingFormat %-d %B %Y
endif

" ftplugin/ruby.vim
if exists('g:loaded_surround') && !exists('b:surround_'.char2nr(':'))
  let b:surround_{char2nr(':')} = ":\r"
endif

Beachten Sie, dass sich die obigen Bits in Dateien befinden, die nach normalen Plugins ausgewertet werden, hier ein ftplugin und eine Datei im after/pluginVerzeichnis.

Eine andere Option wäre die Verwendung von try / catch-Blöcken, obwohl hierfür mindestens Version 7.0 erforderlich ist:

if v:version >= 700
    try
        runtime bundle/pathogen/autoload/pathogen.vim
        call pathogen#infect()
    catch
    endtry
endif

Wenn etwas in dem tryAbschnitt dieses Blocks fehlschlägt, wird zum catchAbschnitt gesprungen . Da der catchAbschnitt leer ist, wird er nach der endtryAnweisung mit dem Rest der Initialisierungsdatei fortgesetzt .

Da hierbei der Code manuell geladen wird und nicht ein bereits geladenes Plugin erforderlich ist, kann dies in der .vimrc-Datei selbst erfolgen.


Können Sie die Versionsanforderungen für das tryKonstrukt hinzufügen ? Würde der alte Vim das verstehen? Dh wann wurde es eingeführt. Danke und +1 fürs Erste.
0xC0000022L

1
Ich habe Informationen über die erforderliche Version hinzugefügt.
qqx

Ich denke, die letzte Lösung mit dem Versions-Check trysollte funktionieren. Danke vielmals. Mal sehen, ob noch eine andere Antwort eintrifft. Ansonsten nehme ich natürlich deins an.
0xC0000022L

ah, natürlich deaktiviert dies das Plugin auf 6.x-Versionen. Hmmm ... muss etwas besseres finden, aber das wird in der Zwischenzeit funktionieren. Vielen Dank.
0xC0000022L

Noch eine andere Alternative ist die Verwendung :silent! {cmd}, die den Fehler unterdrückt, wenn er {cmd}nicht existiert. Dies funktioniert sogar in Vim 6.
Ingo Karkat

7

Meine bevorzugte Methode ist nur, die Existenz der Plugin-Datei zu überprüfen. Ich finde das einfacher.

if !empty(glob("path/to/plugin.vim"))
   echo "File exists."
endif

4

Dies wollte ich erreichen, indem ich meine Vim-Konfiguration .vimrcin mehreren after/Verzeichnissen zusammen hielt. Dies ist die Lösung, die ich mir ausgedacht habe:

  1. Überprüfen Sie die Existenz jedes Plugins, indem Sie nach einem einzelnen Befehl suchen, den es bereitstellt exists(), und legen Sie dessen Optionen fest, falls vorhanden. (Dies ist genau wie in der akzeptierten Antwort.)

  2. Setzen Sie alle Optionen, die auf die obige Weise festgelegt wurden, in eine Funktion (die SetPluginOptionsNow()in meinem Code aufgerufen wird ).

  3. Rufen Sie diese Funktion für das VimEnterEreignis auf, das beim Aufrufen einer neuen Vim-Sitzung ausgelöst wird - aber entscheidend, nachdem alle Plugins geladen wurden. Aus diesem Grund können unsere exists()Checks problemlos nach Plugin-Funktionen suchen.

Hier ist ein Beispiel aus diesem Teil von mir .vimrc.

""" PLUGIN-SPECIFIC OPTIONS
" These are "supposed to be" set in after/plugin directory, but then
" cross-platform synchronization would get even messier. So, au VimEnter it is. 

function! SetPluginOptionsNow()


    " NERDTree Options
    if exists(":NERDTree")
        map <F10> :NERDTreeToggle<CR>
    endif

    " Syntastic Options
    if exists(":SyntasticCheck")
        let g:syntastic_stl_format = '[Syntax: line:%F (%e+%w)]'
        set statusline+=%#warningmsg#
        set statusline+=%{SyntasticStatuslineFlag()}
        set statusline+=%*
        " and so on...

endfunction

au VimEnter * call SetPluginOptionsNow()
""" END OF PLUGIN-SPECIFIC OPTIONS

diese antwort passt nicht zu vim-airline. Insbesondere das Warten auf das VimEnter-Ereignis, um Dinge wie anzugeben, airline_themescheint eine Reihe von Fehlern auszulösen ... Ich bin mir nicht sicher, warum.
StevieP

3

Noch eine andere Alternative ist die Verwendung :silent! {cmd}, die den Fehler unterdrückt, wenn er {cmd}nicht existiert. Der Hauptvorteil ist, dass es sich um einen kurzen Einzelbefehl handelt. Dies funktioniert sogar in Vim 6 und ist ideal für optionale Dinge.

Beispielsweise wird es von Plugins verwendet, die repeat.vim von Tim Pope verwenden , um Zuordnungen wiederholbar zu machen.


Möchten Sie mit !silent runtime ftplugin/man.vim | filetype on | filetype plugin on | filetype indent onwork alle Befehle beenden, die dem folgen, !silentoder ist das immer spezifisch für den nächsten Befehl?
0xC0000022L

Es ist :silent! ist nicht der !silentFall und gilt für alle enthaltenen Befehle, außer wenn :unsilentsie irgendwo im Inneren verwendet werden. (Aber das ist selten.)
Ingo Karkat

Hoppla, jetzt im Kommentar schwer zu beheben. Aber verstanden. Vielen Dank.
0xC0000022L

1

Ursprünglich in einer anderen Frage gepostet: /programming//a/48178537/2843583

Alternativ können Sie auch einen regulären Ausdruck verwenden, um zu entscheiden, ob das Plugin in Ihrem runtimepath:

if &rtp =~ 'plugin-name'
    ...
endif

Dies hat den Vorteil, dass es mit Plugins funktioniert, die nur Vimscript-Code im autoloadVerzeichnis haben, was wiederum nicht erkannt werden kann, wenn .vimrc anfänglich analysiert wird, da die Autoload-Snippets zum Zeitpunkt eines Funktionsaufrufs geladen werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.