Gracefully degrading .vimrc

If you work on many machines with varying operating systems (Windows, GNU/Linux, MacOS X, BSD) and in various upgrade states, particularly if some of the machines are a lot older or have more minimal or custom installations of Vim, you might not be using your .vimrc file on all of them because it includes features that aren’t available on some other machines, meaning that Vim spits a lot of errors at you on startup.

This might have prompted you to perhaps keep a simpler .vimrc file, a “lesser” .vimrc, that you put onto your remote machines, and you keep the “real” .vimrc on your own machine to include lines that use all of the features only available to you on that machine. If you like to version your configuration files, maintaining and testing both of the .vimrc files on all the machines gets old fast; it would be much better to have a single .vimrc file that simply ignored configuration it didn’t understand. There are several ways to approach this.

Check features

Perhaps the best way to manage this is to group all of your configuration items by Vim feature, and to check for their presence in your .vimrc file before attempting to set any of the relevant options. You can do this with the has() function. As an example, here’s a stanza from my .vimrc:

if has("spell")
    set spelllang=en_nz
    nnoremap <leader>s :set spell!<CR>
endif

I set the spellang option and perform the remapping only if the +spell feature is actually available.

If an option is dependent on a feature having been compiled into Vim, you can usually tell by calling :help on it and looking for a phrase like “not available when compiled without the +xyz feature.” You can also view a list all the features available with :help feature-list, and see which features are compiled into a given vim binary with the --version parameter:

$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Feb 11 2012 03:54:05) Included patches: 1-429
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by jamessan@debian.org
Huge version with GTK2 GUI.  Features included (+) or not (-):
+arabic +autocmd +balloon_eval +browse ++builtin_terms +byte_offset +cindent
+clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
+conceal +cryptv +cscope +cursorbind +cursorshape +dialog_con_gui +diff ...

There are certain special features, like +unix, that you can use to check whether the Vim instance running is on a platform suitable for an option or not. I find this is handy for choosing the correct syntax for specifying fonts on Windows:

if has("unix")
    set guifont=Inconsolata\ 14
else
    set guifont=Consolas:h12
endif

Check options

You can check whether an option itself exists rather than a feature with exists():

if exists("&foldenable")
    set foldenable
endif

Check version number

Another way of filtering out options for older versions of Vim is by version number, which you can perform by checking the value of v:version. For example, to only set folding options if you’re working with at least Vim 7, you could do:

if v:version >= 700
    set foldenable
endif

In this particular case, though, it’s a little clearer and more robust to check the condition with if has("folding"), because the version number being recent enough does not necessarily mean the feature exists. However, one good application of using version numbers is fixing bugs or unexpected behaviour in older instances of Vim, to make it behave consistently with newer versions, or even vice-versa if necessary.

Silent calls

If you can’t find a way to filter by feature or version number, a simple way to suppress any error messages from a configuration line is to preface it with silent!. I find this is a nice compact way to call plugin-dependent functions like pathogen#infect(), or custom colorschemes that you can’t be sure actually exist on the machine:

silent! call pathogen#infect()
silent! colorscheme zellner

Try/Catch/If

If you’re not dealing with versions of Vim older than 7.0, another possibility is the try/catch/endtry block. This is handy for setting a default or fallback option if a call fails, such as selecting colorschemes:

try
    colorscheme zenburn
catch
    colorscheme torte
endtry

This is my least-favoured method of making .vimrc files degrade gracefully, as it breaks completely on older instances of Vim.

Thanks to Reddit user bouncingsoul for suggesting the second method which I initially missed.