Как я могу проверить плагины и включать их, только если они существуют в .vimrc?

14

По моему .vimrcя пытаюсь использовать ftpluginи, очевидно, использовать некоторые команды, относящиеся к этому, при условии, что он был загружен успешно. Тем не менее, я столкнулся с несколькими старыми машинами, на которых не установлен плагин. Можно ли как-то сделать загрузку этого плагина условной и добавить filetype onи аналогичные директивы в один и тот же условный блок?

Я видел, что есть условия для цветовых схем и версии Vim, но я не видел пример, который проверял бы плагин (или не распознавал его).

NB: будь осторожен, я начинающий VimScript.

0xC0000022L
источник
1
Обратите внимание, что плагины загружаются после того ~/.vimrc, как вы , поэтому вы не сможете протестировать эффекты плагина в вашем, ~/.vimrcесли вы не протестируете на наличие файла плагина или не отложите тест до тех пор, пока плагины не будут загружены автокомандой, такой как VimEnter.
garyjohn
@garyjohn: ага, это интересно. Потому что этот вид противоречит существующему ответу. Не могли бы вы написать это как ответ?
0xC0000022L
Я отредактировал свой ответ, чтобы несколько решить эту проблему.
qqx
Мой комментарий не противоречил ответу qqx; оно должно было привлечь внимание к пункту, который мог быть упущен, если бы кто-то не внимательно прочитал ответ qqx или сделал из него неправильные выводы. Ответ был хорош для начала и теперь еще яснее.
garyjohn

Ответы:

19

Вы можете заключить этот блок в условие, которое использует exists()функцию, чтобы проверить, известна ли vim переменная, команда или функция, определенная плагином.

Вот пара битов, которые у меня есть в файлах в ~ / .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

Обратите внимание, что приведенные выше биты находятся в файлах, которые оцениваются после обычных плагинов, здесь ftplugin и файл в after/pluginкаталоге.

Другой вариант - использовать блоки try / catch, хотя для этого требуется как минимум vim 7.0:

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

Если что-то в tryразделе этого блока выходит из строя, оно переходит к catchразделу. Поскольку catchраздел пуст, он просто продолжит работу с остальной частью файла инициализации после endtryоператора.

Поскольку это загрузка кода вручную, а не использование уже загруженного плагина, это можно сделать в самом файле .vimrc.

qqx
источник
Не могли бы вы добавить требования к версии для tryконструкции? Старый Вим поймет это? Т.е. когда это было введено. Спасибо и +1 на данный момент.
0xC0000022L
1
Я добавил информацию о требуемой версии.
qqx
Я думаю, что последнее решение с проверкой версии tryдолжно работать. Большое спасибо. Посмотрим, будет ли еще один ответ. В противном случае я, конечно, приму ваше.
0xC0000022L
ну, конечно, это отключает плагин на версии 6.x. Хммм ... нужно найти что-то получше, но пока что это сработает. Благодарю.
0xC0000022L
Используется еще одна альтернатива :silent! {cmd}, которая подавляет ошибку, когда {cmd}ее не существует. Это даже работает в Vim 6.
Инго Каркат
7

Мой предпочтительный метод - просто проверить наличие файла плагина. Я считаю это проще.

if !empty(glob("path/to/plugin.vim"))
   echo "File exists."
endif
user3751385
источник
4

Я хотел достичь этого, сохраняя конфигурацию Vim вместе .vimrc, а не в куче after/каталогов. Это решение, которое я придумал:

  1. Проверьте существование каждого плагина, проверив наличие любой отдельной команды, которую он предоставляет exists(), и установите его параметры, если он существует. (Это так же, как в принятом ответе.)

  2. Поместите все параметры, указанные выше, в функцию (вызываемую SetPluginOptionsNow()в моем коде).

  3. Вызывайте эту функцию для VimEnterсобытия, которое запускается при входе в новый сеанс Vim, но, что важно, после загрузки всех плагинов. Из-за этого наши exists()проверки могут без проблем проверять функции плагина.

Вот образец из этой части моей .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 - Восстановить Монику
источник
этот ответ не подходит для vim-Airlines. В частности, ожидание события VimEnter для указания таких вещей, как airline_themeкажется, вызывает кучу ошибок ... Я не совсем уверен, почему.
StevieP
3

Используется еще одна альтернатива :silent! {cmd}, которая подавляет ошибку, когда {cmd}ее не существует. Главное преимущество в том, что это короткая одиночная команда. Это даже работает в Vim 6 и отлично подходит для дополнительных вещей.

Например, он используется плагинами, которые используют repeat.vim Тима Попа для повторения отображений.

Инго Каркат
источник
Будет ли что-то вроде !silent runtime ftplugin/man.vim | filetype on | filetype plugin on | filetype indent onработы, чтобы закрыть все команды, следующие за !silentили это всегда специфично для следующей команды?
0xC0000022L
Это :silent!не так !silent, и это относится ко всем содержащимся командам, за исключением случаев, когда :unsilentиспользуется где-то внутри. (Но это редко.)
Инго Каркат
К сожалению, сейчас это трудно исправить в комментарии. Но получил это. Благодарю.
0xC0000022L
1

Первоначально опубликовано в другой вопрос: /programming//a/48178537/2843583

В качестве альтернативы вы также можете использовать регулярное выражение, чтобы решить, есть ли плагин под рукой runtimepath:

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

Преимущество этого заключается в том, что он работает с плагинами, которые имеют в autoloadкаталоге только код vimscript , который, в свою очередь, не может быть обнаружен при первоначальном анализе .vimrc, поскольку фрагменты автозагрузки загружаются во время вызова функции.

bergercookie
источник