我如何测试插件,并且仅在.vimrc中存在插件时才包括它们?


14

在我.vimrc本人中,我尝试使用ftplugin并且显然使用一些与此命令有关的命令,并假设它已成功加载。但是,我现在遇到了几台未安装插件的旧机器。我可以以某种方式使此插件的加载成为条件,并将add filetype on和类似的指令加载到同一条件块中吗?

我已经看到了配色方案和Vim版本的条件,但是我还没有看到可以检查插件(或无法识别插件)的示例。

注意:请保持温柔,我是VimScript的初学者。


1
请注意,插件是在之后加载的~/.vimrc,因此~/.vimrc除非您测试插件文件的存在或将测试推迟到使用自动命令(例如, VimEnter。
garyjohn

@garyjohn:啊哈,这很有趣。因为这种矛盾与现有的答案。你能把它写出来作为答案吗?
0xC0000022L13年

我已经编辑了答案,以解决该问题。
qqx

我的评论与qqx的回答并不矛盾。这是为了引起人们的注意,如果不仔细阅读qqx的答案或从中做出错误的推断,可能会错过这一点。答案从开始就很好,现在更清晰了。
garyjohn

Answers:


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文件本身中完成。


8

我的首选方法是检查插件文件是否存在。我觉得这更简单。

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

听起来很合理,但是基本路径是什么?Vim是否自动(通常是~/.vim)回家?
0xC0000022L

取决于您的.vimrc配置和软件包管理首选项。我这样做:if filereadable($HOME."/.vim/plugins.vim") source ${HOME}/.vim/plugins.vim 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

这个答案对vim-airline来说不太合适。特别是,等待VimEnter事件指定类似的东西airline_theme似乎会引发很多错误……我不确定为什么。
StevieP '16

3

还有一种替代方法是使用:silent! {cmd},当{cmd}不存在该错误时可以抑制该错误。主要优点是它是一个简短的命令。这甚至可以在Vim 6中使用,非常适合可选的东西。

例如,使用Tim Pope的repeat.vim的插件会使用来使映射可重复。


它是:silent!,不是!silent,它适用于所有包含的命令,除了何时:unsilent在内部某处使用。(但这很少见。)
Ingo Karkat 2013年

2

最初发布在另一个问题中:https : //stackoverflow.com/a/48178537/2843583

作为替代方案,您也可以使用regexp来确定当前的插件是否在您的插件中runtimepath

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

这样做的好处是,它可以与autoload目录中仅包含vimscript代码的插件一起使用,而在最初解析.vimrc时,由于在函数调用时会加载自动加载片段,因此无法检测到插件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.