How can I test for plugins and only include them if they exist in .vimrc?
In my .vimrc
I am trying to use ftplugin
and obviously use some commands relating to that under the assumption that it was loaded successfully. However, I have now encountered a few old machines that don't have the plugin installed. Can I somehow make loading of this plugin conditional and add filetype on
and similar directives into the same conditional block?
I have seen there are conditions for color schemes and the Vim version, but I haven't seen an example that would check for the plugin (or didn't recognize it).
NB: Be gentle, I am a VimScript beginner.
You can wrap that block in a conditional which uses the exists()
function to
check if a variable, command or function defined by the plugin is known to vim.
Here are a couple bits that I have in files under ~/.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
Note that the above bits are in files that get evaluated after normal plugins,
here an ftplugin, and a file in the after/plugin
directory.
Another option would be to use try/catch blocks, although this requires at least vim 7.0:
if v:version >= 700
try
runtime bundle/pathogen/autoload/pathogen.vim
call pathogen#infect()
catch
endtry
endif
Once something in the try
section of that block fails it will skip to the
catch
section. Since the catch
section is empty, it will just continue on
with the remainder of the initialization file after the endtry
statement.
Since this is manually loading code rather than relying on a plugin being already loaded, this can be done in the .vimrc file itself.
My preferred method is just to check for the existence of the plugin file. I find this simpler.
if !empty(glob("path/to/plugin.vim"))
echo "File exists."
endif
I wanted to achieve this while keeping my Vim configuration together within .vimrc
, rather than in a bunch of after/
directories. This is the solution I came up with:
Check each plugin's existence by checking for any single command that it provides with
exists()
, and set its options if it does exist. (This is just like in the accepted answer.)Put all the options set in the above manner within a function (called
SetPluginOptionsNow()
in my code).Call this function on the
VimEnter
event, which is triggered while entering a new Vim session - but crucially, after the plugins have all been loaded. Because of this fact, ourexists()
checks can check for the plugin functions without a problem.
Here's a sample from that part of my .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
Yet another alternative is using :silent! {cmd}
, which suppresses the error when {cmd}
does not exist. The main benefit is that it's a short single command. This even works in Vim 6, and is great for optional stuff.
For example, it is used by plugins that use Tim Pope's repeat.vim to make mappings repeatable.