Jak mogę przetestować wtyczki i uwzględnić je tylko, jeśli istnieją w .vimrc?

14

W mojej .vimrcusiłuję użyć ftplugini oczywiście użyć niektórych poleceń związanych z tym przy założeniu, że został pomyślnie załadowany. Jednak spotkałem się teraz z kilkoma starymi komputerami, które nie mają zainstalowanej wtyczki. Czy mogę w jakiś sposób uzależnić ładowanie tej wtyczki i dodać filetype oni podobne dyrektywy do tego samego bloku warunkowego?

Widziałem, że istnieją warunki dla schematów kolorów i wersji Vima, ale nie widziałem przykładu, który sprawdziłby wtyczkę (lub jej nie rozpoznał).

NB: Bądź łagodny, jestem początkującym w VimScript.

0xC0000022L
źródło
1
Zauważ, że wtyczki są ładowane po twoim ~/.vimrc, więc nie będziesz w stanie przetestować efektów wtyczki w swoim wnętrzu, ~/.vimrcchyba że przetestujesz na obecność pliku wtyczek lub odroczysz test, dopóki wtyczki nie zostaną załadowane za pomocą komendy automatycznej, takiej jak VimEnter.
garyjohn
@garyjohn: aha, to interesujące. Ponieważ ten rodzaj zaprzecza istniejącej odpowiedzi. Czy możesz napisać to jako odpowiedź?
0xC0000022L
Zredagowałem swoją odpowiedź, aby w pewnym stopniu rozwiązać ten problem.
qqx
Mój komentarz nie jest sprzeczny z odpowiedzią qqx; miało na celu zwrócenie uwagi na kwestię, która mogłaby zostać przeoczona, gdyby nie przeczytano uważnie odpowiedzi qqx lub wyciągnięto z niej nieprawidłowe wnioski. Odpowiedź była dobra na początek i jest teraz jeszcze jaśniejsza.
garyjohn

Odpowiedzi:

19

Możesz zawinąć ten blok w warunek, który używa exists()funkcji do sprawdzenia, czy zmienna, polecenie lub funkcja zdefiniowana przez wtyczkę jest znana z vim.

Oto kilka bitów, które mam w plikach w ~ / .vim:

" 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

Zauważ, że powyższe bity znajdują się w plikach, które są oceniane po normalnych wtyczkach, tutaj ftplugin i plik w after/pluginkatalogu.

Inną opcją byłoby użycie bloków try / catch, chociaż wymaga to co najmniej vim 7.0:

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

Gdy coś w trysekcji tego bloku zawiedzie, przejdzie do catchsekcji. Ponieważ catchsekcja jest pusta, będzie kontynuowana z pozostałą częścią pliku inicjalizacyjnego po endtryinstrukcji.

Ponieważ jest to ręczne ładowanie kodu zamiast poleganie na już załadowanej wtyczce, można to zrobić w samym pliku .vimrc.

qqx
źródło
8

Moją preferowaną metodą jest po prostu sprawdzenie istnienia pliku wtyczki. Uważam to za prostsze.

if !empty(glob("path/to/plugin.vim"))
   echo "File exists."
endif
użytkownik3751385
źródło
Brzmi rozsądnie, ale jaka jest podstawowa ścieżka? Czy to automatycznie dom Vima (tj. Zwykle ~/.vim)?
0xC0000022L
Zależy od konfiguracji .vimrc i preferencji zarządzania pakietami. Robię to:if filereadable($HOME."/.vim/plugins.vim") source ${HOME}/.vim/plugins.vim endif
user3751385
dzięki, super. Bardziej martwiłem się, że to, co dałeś, sugeruje podstawową ścieżkę.
0xC0000022L
4

Chciałem to osiągnąć, utrzymując moją konfigurację Vima razem .vimrc, zamiast w kilku after/katalogach. Oto rozwiązanie, które wymyśliłem:

  1. Sprawdź istnienie każdej wtyczki, sprawdzając dostępne dla niej pojedyncze polecenie exists()i ustaw jej opcje, jeśli istnieje. (Jest tak jak w zaakceptowanej odpowiedzi.)

  2. Umieść wszystkie opcje ustawione w powyższy sposób w funkcji (wywołanej SetPluginOptionsNow()w moim kodzie).

  3. Wywołanie tej funkcji na VimEnterwydarzenie, które jest wyzwalane podczas wprowadzania nowej sesji Vima - ale co najważniejsze, po wtyczek wszystkie zostały załadowane. Z tego powodu nasze exists()kontrole mogą bez problemu sprawdzać funkcje wtyczek.

Oto próbka z tej części mojej .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
sundar - Przywróć Monikę
źródło
ta odpowiedź nie pasuje do vim-Airlines. W szczególności oczekiwanie na zdarzenie VimEnter, które określa takie rzeczy, airline_themewydaje się powodować wiele błędów ... Nie jestem pewien, dlaczego.
StevieP,
3

Jest jeszcze jedna alternatywa :silent! {cmd}, która eliminuje błąd, gdy {cmd}nie istnieje. Główną zaletą jest to, że jest to krótkie pojedyncze polecenie. Działa to nawet w Vimie 6 i doskonale nadaje się do opcjonalnych rzeczy.

Na przykład jest używany przez wtyczki, które używają powtórzenia Tima Pope'a, aby mapowanie było powtarzalne.

Ingo Karkat
źródło
To :silent!, nie !silent, i to odnosi się do wszystkich poleceń zawartych, z wyjątkiem, gdy :unsilentjest używany gdzieś w środku. (Ale to rzadkie.)
Ingo Karkat
2

Początkowo opublikowane w innym pytaniu: /programming//a/48178537/2843583

Alternatywnie możesz również użyć wyrażenia regularnego, aby zdecydować, czy dostępna wtyczka znajduje się w runtimepath:

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

Ma to tę zaletę, że działa z wtyczkami, które mają tylko katalog vimscript w autoloadkatalogu, którego z kolei nie można wykryć, gdy .vimrc jest wstępnie analizowany, ponieważ fragmenty autoload są ładowane w czasie wywołania funkcji.

bergercookie
źródło