Vim/Neovim — Managing Multiple Project Settings
Managing project-specific settings for Vim/Neovim projects.

Overview
I talked about managing multiple databases and projects in my previous articles. On some occasions, you may have a need to manage multiple projects with configurations only specific to the projects.
In this article, let’s explore the available options we have in Vim/Neovim. I will start with the simplest solution and then move on to explore plugins we can use.
exrc, vimrc, nvimrc
If you set the exrc
option in your .vimrc
or init.vim
file, Vim/Neovim will execute .exrc
(for both Vim/Neovim), .vimrc
(Vim), .nvimrc
(Neovim) found in the current directory when Vim/Neovim is started.
set exrc
For security reason, you may also want to set the secure
option together (refer to :h secure
)
set secure exrc
When secure
is on, :autocmd
, shell
and write
commands are not allowed in .nvimrc
, .vimrc
and .exrc
in the current directory and map commands are displayed.
From the documentation for the secure
option,
When on, “:autocmd”, shell and write commands are not allowed in
“.nvimrc” and “.exrc” in the current directory and map commands are
displayed. Switch it off only if you know that you will not run into
problems, or when the ‘exrc’ option is off. On Unix this option is
only used if the “.nvimrc” or “.exrc” is not owned by you. This can be
dangerous if the systems allows users to do a “chown”. You better set
‘secure’ at the end of your |init.vim| then.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
Per Neovim documentation for exrc
option,
If the 'exrc' option is on (which is NOT the default), the current
directory is searched for two files. The first that exists is used,
the others are ignored.
- The file ".nvimrc"
- The file ".exrc"
Per Vim documentation for exrc
option,
If the ‘exrc’ option is on (which is NOT the default), the current
directory is searched for three files. The first that exists is used,
the others are ignored.
— The file “.vimrc” (for Unix, Amiga) (*)
“_vimrc” (for Win32) (*)
— The file “_vimrc” (for Unix, Amiga) (*)
“.vimrc” (for Win32) (*)
— The file “.exrc” (for Unix, Amiga)
“_exrc” (for Win32)
Plugins for Local vimrc
Alternatively, you can use plugins to enable per-directory configurations. You can make use of vim-localvimrc and vim-localrc for this purpose, which may be more secure than setting exrc
.
Built-in FileType Plugin
If your projects are of different languages, one good option is definitely to make sure of the built-in file type plugin (:h ftplugin
).
For Vim, the folder to use is normally under ~/.vim/after/ftplugin
. E.g. if you want to override the default Javascript settings, create a file called javascript.vim
in this folder with the custom settings.
For Neovim, the folder to use is normally under ~/.config/nvim/after/ftplugin
.
E.g. if you go to the default system ftplugin
folder (In my case is /usr/local/share/nvim
), you can see the default configurations for all file types.

File Type
Plugins for NeovimAutoCmd
Another option is to use the auto command. There are multiple ways you can use it.
Language-Specific Settings
You can set language-specific setting, e.g.
autocmd FileType markdown setlocal spell
autocmd FileType html setlocal shiftwidth=2
autocmd FileType php,html setlocal shiftwidth=2 expandtab
Or you can source a file if you have many settings, e.g.
autocmd FileType markdown source ~/.vim/settings/mysettings.vim
Centralized Settings
You can also centralize your settings to a folder using the auto command (:h autocmd-pattern)
, e.g.
:autocmd BufRead,BufNewFile /path/to/dir/** setlocal ts=4 sw=4
Also, read this chapter fromLearn Vimscript the Hard Way
to understand the pitfall of auto command, and how to avoid creating duplicate auto commands.
editor-config
editorconfig-vim is an EditorConfig plugin for Vim/Neovim. Basically, you just need to create an .editorconfig
file in the project folder and Vim/Neovim will use the settings using this plugin.
The EditorConfig Vim plugin supports the following EditorConfig properties:
indent_style
indent_size
tab_width
end_of_line
charset
insert_final_newline
trim_trailing_whitespace
max_line_length
root
(only used by EditorConfig core)
From Vim/Nevom, type :h editorconfig
to get more details from the documentation once you installed it,
vim-sleuth
This plugin may not allow you to manually configure project-specific settings. vim-sleuth automatically adjusts 'shiftwidth'
and 'expandtab'
heuristically based on the current file, or, in the case the current file is new, blank, or otherwise insufficient, by looking at other files of the same type in the current and parent directories.
vim-projectionist
projectionist.vim provides granular project configuration using “projections”.
Let’s see a trivial example to set a color scheme for a project.
Create a file called .projections.json
in a folder with the following content.
{
"*.html": {
"colorscheme": [
"onedark"
]
}
}
Projectionist will detect this file and set a buffer-local variable (b:projectionist
) whenever an HTML file is loaded.

Using the dofiles I developed in my previous article, create a plugin/projectionist.vim
file with the following content.
augroup change_colorscheme
autocmd!
autocmd User ProjectionistActivate call s:change_colorscheme()
augroup ENDfunction! s:change_colorscheme() abort
let l:colorscheme = projectionist#query('colorscheme')
if len(l:colorscheme) > 0
execute 'colorscheme '.l:colorscheme[0][1][0]
endif
endfunction
Restat Vim/Neovim, and now if you open or create an HTML file in the folder the color scheme will automatically change to onedark
.

Projectionist also has features that make navigating project easier.
E.g. with the following .projections.json
which describes my project structure, I can navigate the project files easily.
{
"*.html": {
"colorscheme": [
"onedark"
]
},
"libs/*.py": {
"alternate": "tests/test_{}.py",
"type": "source"
},
"tests/test_*.py": {
"alternate": "libs/{}.py",
"type": "test"
},
"cli.py": {
"type": "main"
},
"lib/models/*.py": {
"type": "model"
}
}

Now,
- type
:Emain
will opencli.py
- open
utils.py
, type:A
andtest_utils.py
will be loaded. - open
test_utils.py,
type:A
andutils.py
will be loaded. - type
:Emodel users
andusers.py
will be loaded.
You have various options to open the file in split, tab, etc. Type :h projectionist
to look at the documentation.
If you are looking for a Lua-based plugin you can try out vim-projectconfig.
Do also check out the following articles!