34

I have different option for each working directory. I don't want to set these options every time I work. I know I can append vimrc file for the options but I don't want to use the same configuration in every directory. How can I do with this situation?

Example:

For javascript project, I want to load settings from ~/.vimrc_js

For Python project, I want to load settings from ~/.vimrc_py

Amp Tanawat
  • 598
  • 1
  • 5
  • 10
  • 9
    [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) alert! It looks *a lot* like you want filetype-specific settings, not directory-specific settings. – romainl Sep 21 '13 at 15:02
  • 3
    @romainl that just an example. I also need many directory-specific settings such as dictionary I want to include for this project. Sorry for made it unclear. – Amp Tanawat Sep 23 '13 at 04:57

5 Answers5

36

If each project uses a distinct language, the built-in filetype plugin (ftplugin) mechanism, as described by Jamie Schembri, will work just fine. If you really need different settings for the same type of files, read on:

Central configuration

If it's okay to configure the local exceptions centrally, you can put such autocmds into your ~/.vimrc:

:autocmd BufRead,BufNewFile /path/to/dir/* setlocal ts=4 sw=4

On the other hand, if you want the specific configuration stored with the project (and don't want to embed this in all files via modelines), you have the following two options:

Local config with built-in functionality

If you always start Vim from the project root directory, the built-in

:set exrc

enables the reading of a .vimrc file from the current directory. You can place the :set ts=4 sw=4 commands in there.

Local config through plugin

Otherwise, you need the help of a plugin; there are several on vim.org; I can recommend the localrc plugin, which even allows local filetype-specific configuration.

Note that reading configuration from the file system has security implications; you may want to :set secure.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • 2
    `:set secure` is completely useless: just put `call feedkeys(":!echo 1>2\n")` into `.exrc` and watch file `2` appear. Thus you are either sure that all such files appear only from trusted sources or never use `set exrc`. – ZyX Sep 21 '13 at 18:36
  • 1
    No, I am mistaking. It is useless completely because “On Unix this option is only used if the ".vimrc" or ".exrc" is not owned by you.”: this allows `call feedkeys()` regardless of `set secure`. – ZyX Sep 21 '13 at 18:47
  • 1
    Also interesting ways of bypassing `set secure`: `let g:http_netrw_cmd="some cmd that downloads and starts remote shell"` assuming one knows that target is using netrw for viewing remote files; `command -nargs=? -bar AuV :execute "!some cmd…"|AuVimDiff ` assuming one knows that target is using aurum and its `AuVimDiff` command and so on. It is better to know that 'secure' is useless then to rely on what it does. If malicious constructs appear in the file it is 90% targeted attack. `set secure` is useless against this kind of attacks. – ZyX Sep 21 '13 at 18:59
  • 1
    It is also useless against malicious constructs pushed to public repository: after cloning VCSes assign current user as an owner to the files in working directory thus bypassing `set secure` on Unix systems. – ZyX Sep 21 '13 at 19:01
  • 4
    +1 for `set exrc`. I feel like everyone overcomplicates this question far more than the obvious answer, which is this. – underscore_d Sep 25 '17 at 21:34
  • Great Explanation for local .vimrc! Thanks VIM! – Benyamin Limanto Oct 05 '19 at 07:20
  • how come `:set exrc` doesn't work for me? When I add `set path+=...` in ~/.vimrc, the `fo` command works but when I add the same setting in a local .vimrc file, it doesn't work. I'm using /usr/bin/vim.gtk3 through alternative system. – Chan Kim Jun 17 '21 at 02:02
  • In my case if I do `:source .vimrc`, the local .vimrc takes effect. – Chan Kim Jul 19 '23 at 06:15
10

Filetype Plugin

This is what you're probably looking for, and is a very neat approach. You'll need to set filetype plugin on in your vimrc to get this to work. A file must then be created at ~/.vim/ftplugin/<language>.vim which will be loaded automatically for any buffers using that language.

For example, instead of writing your JavaScript settings to ~/.vimrc_js, write them to ~/.vim/ftplugin/javascript.vim.

Autocmd

autocmd is the simplest way to set something on a language-specific basis:

autocmd Filetype <language> <setting>

This goes directly in your vimrc and will load settings for a specified filetype only.

To enable spellcheck across various text files, for example, one could use:

autocmd FileType markdown,tex,textile setlocal spell

You can set multiple settings at once by separating them with a pipe, those this quickly becomes unwieldy:

autocmd FileType php setlocal shiftwidth=4 tabstop=4|let php_sql_query=1

AutoCMD + Source

On rare occasions you might have enough settings to warrant a separate file, but would like to load them for multiple languages. Using filetype plugins, you'll end up with duplicate files or symlinks.

A simple alternative is to fall back to autocmd, but instead of writing the settings in one big line, you can instead source a file. For example:

autocmd FileType markdown,tex,textile source ~/.vim/lang_settings/text.vim
Jamie Schembri
  • 6,047
  • 4
  • 25
  • 37
7

You can try the localvimrc plugin. It tries to load .lvimrc in your project directory or the directories above. You can put your settings there for each project.

xuhdev
  • 8,018
  • 2
  • 41
  • 69
2

Another solution is EditorConfig. It sets coding styles for different projects or filetypes. It works with Vim, but it is editor agnostic, so you can use the .editorconfig file with other text editors (SublimeText2, Notepad++, Vim, Emacs, Textmate, Gedit) or IDE (idea-based IDE's, RubyMine, PHPStorm, Visual Studio).

Jose Elera
  • 938
  • 9
  • 16
0

Here's another option, similar to @Ingo Karkat's first suggestion, except that it allows you to have separate vimrc files for each working directory (which is a closer answer to the OP's question). It's a bit hackier than using one of the plugins available, but it does avoid the security problem of the localvimrc plugin, and lets you store all your vimrc variants in your home directory instead of scattered throughout the different working directories (though it would work just as well if you did have them in the root of each of your relevant working directories.

In .vimrc

if getcwd() =~ 'One Unique Target Directory'
  source ~/.one_unique_vimrc
elseif getcwd() =~ 'Another Unique Target Directory'
  source ~/.another_unique_vimrc
endif

The challenge is that you need to target one vimrc to a unique path - so this wouldn't work so well with the following directory structure - if you've got one vimrc for Foo and one for Baz, there would be some inconsistent behavior ("Why is /Baz/Foo using my /Foo vimrc?!")

/Foo
/Foo/Bar
/Foo/Bar/Baz
/Baz
/Baz/Quux
/Baz/Foo

But it could work well with a directory structure more like this

/Projects/My Greatest App/
/Projects/My Greatest App/src
/Projects/My Greatest App/bin
/Projects/unique.net/
/Projects/unique.net/index.html
/Projects/unique.net/.htaccess

Where you have one vimrc for your 'My Greatest App' and another for your unique website

alexanderbird
  • 3,847
  • 1
  • 26
  • 35