Home

Awesome

local_vimrc : A project management plugin for Vim

The aim of local_vimrc is to apply settings on files from a same project.

A project is defined by a root directory: everything under the root directory belongs to the project. No need to register every single file in the project, they all belong.

Last release Project Stats

Purpose

This plugin presents a solution to Yakov Lerner's question on Vim ML. It searches for _vimrc_local.vim files in the parents directories and sources the one found.

The Initial Question was:

Is it possible, after sourcing ~/.exrc, to traverse from $HOME down to cwd, and source .exrc from every directory if present ? (And if cwd is not under $HOME, just source ~/.exrc). What do I put into .vimrc to do this ?

Example: current dir is ~/a/b/c. Files are sourced in this order: ~/.exrc, then ~/a/.exrc, ~/a/b/.exrc, ~/a/b/c/.exrc. No messages if some of .exrc does not exist.

Requirements / Installation

The latest version of this script requires vim 7.0 and lh-vim-lib v5.2.1+. UT v0.1.0 will be required to execute the unit tests.

The easiest way to install this plugin is with vim-addon-manager, or other plugin managers based on vim-pi, that support vim-addon-files -- as this script specifies its dependencies in vim-addon-file format.

ActivateAddons local_vimrc

Or with vim-flavor which also supports dependencies:

flavor 'LucHermitte/local_vimrc'

With Vundle

Plugin 'LucHermitte/lh-vim-lib'
Plugin 'LucHermitte/local_vimrc'

Or, with a NeoBundle version that doesn't support vim-pi yet:

set rtp+=~/.vim/bundle/NeoBundle.vim/
call neobundle#begin(expand('~/.vim/bundle'))
NeoBundleFetch 'Shougo/NeoBundle.vim'
" Line required to force the right plugin name -> lh-vim-lib, and not trunk
NeoBundle 'LucHermitte/lh-vim-lib', {'name': 'lh-vim-lib'}
" Note: I haven't found the syntax to merge the two NeoBundle lines into one...
NeoBundle 'LucHermitte/local_vimrc', {'depends': 'lh-vim-lib'}
call neobundle#end()

NeoBundleCheck

Usage

Drop a _vimrc_local.vim file into any project root directory, and write it exactly as you would have written a ftplugin.

_vimrc_local.vim content

In other words. The project file is expected to be loaded (/sourced) every time you enter a buffer that corresponds to a file under the project root directory.

As a consequence, you may want to prevent multiple executions of parts the sourced file: almost everything shall remain identical and shall not need to be reset. However some plugins, like alternate (a.vim), rely on global variables to tune their behaviour. The settings (global variables) related to those plugins will require you to update their value every time -- if you expect to have settings that differ from a project to another. In order to support such project-aware setting, local_vimrc lets you in charge of handling anti-reinclusion guards in project configuration files.

For your project settings prefer buffer-local mappings (:h :map-<buffer>), abbreviations (:h :abbreviate-<buffer>), commands (:h :command-buffer), menus (see my fork of buffer-menu), settings (:h :setlocal), and variables (:h local-variable).

N.B.: if you are a plugin writer that want to support configuration variables that'll dynamically adapt to the current project settings, have a look at my lh#option#get() and lh#ft#option#get() functions.

You'll find examples of use in my dedicated repository.

Options

The behaviour of this plugin can be tuned with the following options:

Other Features

Per-project settings and Template Expander Plugins

Sometimes we want to set variables (like a project source directory, or specific template files that override the default project file headers) before other plugins are triggered.
The typical use case will be from the shell:

# There is a _vimrc_local.vim file in /path/to/myproject/
cd /path/to/myproject/submodule42
gvim foobar.h

In order to use myproject settings (naming styles, header guards naming policy, ...), the vimrc_local file needs to be sourced before any template-file is expanded.

This plugin provides the :SourceLocalVimrc command for this purpose. It's up to the Template Expander Plugin to exploit this feature -- as this moment, only my fork of mu-template does.

Automatic increment of vimrc_local script version number

When saved, if the vimrc_local script has a s:k_version variable, it will be incremented automatically. This variable is meant to avoid multiple inclusions of the script for a given buffer. New vimrc_local scripts created with the help of the templates provided with my mu-template fork are making use of this variable.

Security concerns

Thanks to the option g:local_vimrc_options, it's possible to tune which _vimrc_local files are sourced, and how.

The lists

The four lists g:local_vimrc_options.whitelist, g:local_vimrc_options.blacklist, g:local_vimrc_options.asklist, and g:local_vimrc_options.sandboxlist, will hold lists of pathname patterns. Depending on the kind of the pattern that is the best match for the current _vimrc_local file, the file will be either:

Default settings

Tuning the lists

In order to blindly accept _vimrc_local files from projects your are working on, you'll have to add this kind of lines into your .vimrc, after this plugin has been loaded:

" Sourcing the plugin
ActivateAddons local_vimrc
...
" Let's assume you put all projects you are working on in your
" corporation under $HOME/dev/my_corporation/
call lh#local_vimrc#munge('whitelist', $HOME.'/dev/my_corporation')
" But projects from 3rd parties/projects downloaded from the internet go
" into $HOME/dev/3rdparties/
call lh#local_vimrc#munge('blacklist', $HOME.'/dev/3rdparties')

If you want to override default settings, change them in your .vimrc after this plugin has been loaded. e.g.:

ActivateAddons local_vimrc
...
" Remove $HOME from the asklist,
call lh#local_vimrc#filter_list('asklist', 'v:val != $HOME')
" Add it in the sandbox list instead
call lh#local_vimrc#munge('sandboxlist', $HOME)

" Clean the whitelist
let lh#local_vimrc#lists().whitelist = []

Alternatives

To be fair, there exist alternatives.

Modelines

Modelines are particularly limited:

.exrc

Vim natively supports .exrc files (:h .exrc, § d-) when 'exrc' is on. This solution is very similar to local_vimrc. However .exrc files are executed (sourced in Vim jargon) only on buffers (corresponding to files) which are in the exact same directory. Files in subdirectories won't trigger the execution of the project .exrc file.

Autocommands

It's possible to add autocommands in our .vimrc. Autocommands that will detect files under a certain directory to trigger commands (:set xxxxx, :let b:style='alman', :source path/to/project_config.vim, ...).

If the autocommand executes simple commands (instead of sourcing a file), the solution won't scale when new commands will need to be added.

Autocommands won't scale either as a project location may vary :

Project plugin

There exist a quite old (which does NOT mean bad) plugin dedicated to the management of project configuration. I've never used it, I won't be able to tell you why local_vimrc solution is better or not.

Plugins similar to local_vimrc

There exist many plugins with the same name or even with similar purpose. Just to name a few, there is for instance:

TO DO

History