Vim exrc

2 minute read

Updated:

When vim starts up, it reads configurations from many different locations:

  • System rc, /etc/local/blah/blah/vimrc
  • User rc, ~/.vimrc
  • exrc, ./exrc

I’ve only recently learned of the last option.

exrc

The exrc file is configuration file that is local to the current working directory that vim is invoked from. This makes it useful for “workspace” related configurations, such as those that only pertain to a certain repository you’re working in.

An example use case would be if you wanted to use literal tabs for personal repos and a 7-space soft tabs for an open source repo you contribute to. Or if there are a set of abbreviations and mappings that are only useful for certain applications. Such as if you use a common domain specific acronym very frequently (TPS reports) and want it to automatically expand.

Deprecation

This feature is deprecated in Neovim. Not only is it deprecated but it’s kinda already broken with a build of Neovim from November 2019. So it’s straight dropped.

The reason cited is because of exploits and attacks, where you can inadvertently execute malicious code simply by opening up your editor. Vim is powerful and dangerous in this respect (compared to more constrained editors): it allows for executing processes and possibly elevated privileges if ran with sudo (instead of sudoedit).

The suggested workaround is to add autocommands to init.vim that are triggered based on path. Autocommands for buffer events accept a file pattern that you can use to target and add rules. Since these tend to be specific to the system, it’s recommend to add these rules to a init_local.vim that is not checked into your dotfiles.

Adding this code snippet to your init.vim will cause it to source a local, git-ignored file:

execute 'source ' . fnamemodify($MYVIMRC, ':p:h') . '/init_local.vim'

This is like an eval, it executes the string given, which is a hand-formatted way of getting source (dirname $0)/init_local.vim.

" Set tab to be 7 spaces for foo repo and 3 for bar
autocmd BufEnter /home/ipwnponies/repos/foo/*.py set ts=7
autocmd BufEnter /home/ipwnponies/repos/bar/*.py set ts=3

ftplugin

ftplugin is how vim organizes configurations based on filetype. When entering a file, if filetype is on then the configs in corresponding ftplugin are sourced. This is very useful for language specific configs. In fact, it’s how vim-polyglot works and is very nice for organization.

However, there is no support for an exrc-like ftplugin. i.e. configs organized by file type but only the current directory.

If you observe, ftplugin is syntactic sugar for autocmd Filetype foo. It’s such a common use case that it does warrant ftplugin. But without support, we’ll need to manually emulate this the tedious way.

Instead of init_local.vim, consider moving this file to the repo itself. Then you can have an autocmd to source init_local.vim for whitelisted directories. And in the init_local.vim, you can simply use autocmd Filetype as normal.