77

In my .vimrc I've got a generic tab setting of two spaces, and I'd like to override that on a per language basic (that is, four for Python, etc, otherwise use the default), but I'm having trouble finding any good example of this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Magnus Österlind
  • 1,380
  • 1
  • 12
  • 13

5 Answers5

95

These other answers seem way too complex. Instead of messing around with yet more directories and files in your ~/.vim tree, just add the following to your ~/.vimrc.

autocmd Filetype python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4

(you can be l33t and abbreviate parameters to et ts=4 sw=4 sts=4). I found this in Setting Vim whitespace preferences by filetype

Community
  • 1
  • 1
skierpage
  • 2,514
  • 21
  • 19
  • +1 for the option to set it from vimrc. It becomes more important when using a vim package manager (a la vundle) and wouldn't want to start adding configuration in obscure places... – Oren S May 15 '17 at 10:34
56

Just put the settings into the filetype plugin file ~/.vim/ftplugin/LANGUAGE.vim . My ~/.vim/ftplugin/perl.vim contains the lines:

"
" ---------- tabulator / shiftwidth --------------------
"  Set tabulator and shift width to 4 (Perl Style Guide)
"
setlocal  tabstop=4
setlocal  shiftwidth=4
"

These settings will automatically be in effect for each file with file type 'perl' (new or existing).

Fritz G. Mehner
  • 16,550
  • 2
  • 34
  • 41
25

My answer is based on this tip on the VIM Wiki. This answer uses the "after" directory so you won't have to muck with the supplied plugin files for different filetypes.

For example, to specify custom settings for Python files, create a file called python.vim to hold your Python settings:

setlocal expandtab
setlocal shiftwidth=4
setlocal softtabstop=4

Place this file in either

  • ~/.vim/after/ftplugin (Linux)
  • $HOME/vimfiles/after/ftplugin (Windows)

And finally, you must have this in your .vimrc (Linux) or _vimrc (Windows):

filetype plugin indent on
Brian Neal
  • 31,821
  • 7
  • 55
  • 59
  • 1
    @BjornTipling - there is that edit you requested a year ago. :) – Brian Neal Jul 18 '12 at 02:02
  • 1
    Be careful using this technique for HTML files. I found "~/.vim/after/ftplugin/html.vim" changed the settings for PHP files as well, maybe because they're "like" html (vim 7.3 in Ubuntu 12.04). I think putting `autocmd Filetype python setlocal expandtab shiftwidth=4 softtabstop=4` in ~/.vimrc is much clearer and less files to trawl through. – skierpage Aug 26 '12 at 22:42
  • 1
    Maybe you should indicate, as said in the given link, that it is neccesary to add the line `filetype plugin indent on` to your local .vimrc file. – joaquin Nov 14 '12 at 17:17
9

Typically what you do is set up a special vimrc-type file with the settings for a particular language, and then use autocommands in your main .vimrc to execute the special vimrc when necessary. Here's my configuration for Haskell (.hs, etc.) files:

autocmd! BufNewFile,BufReadPre,FileReadPre  *.hs    so ~/.vim/haskell.vim
autocmd! BufNewFile,BufReadPre,FileReadPre  *.hsc   so ~/.vim/haskell.vim
autocmd! BufNewFile,BufReadPre,FileReadPre  *.lhs   so ~/.vim/haskell.vim
autocmd! BufNewFile,BufReadPre,FileReadPre  *.cabal so ~/.vim/haskell.vim

My ~/.vim/haskell.vim does stuff like "set expandtab" to use spaces instead of tabs, and all sorts of other magic for formatting and things like this. You can often download good versions of these for various languages from http://vim.org and other sites.

Note that you can do a lot more than just change vim settings. For example, you can run the file through a filter before and after editing:

" Edit gpg-encrypted ascii-armoured files
autocmd! BufReadPre,FileReadPre      *.asc  set bin
autocmd  BufReadPost,FileReadPost    *.asc  '[,']!gpg -q -d
autocmd  BufReadPost,FileReadPost    *.asc  set nobin
autocmd! BufWritePre,FileWritePre    *.asc  set bin
autocmd  BufWritePre,FileWritePre    *.asc  '[,']!gpg -e
autocmd  BufWritePost,FileWritePost  *.asc  undo
autocmd  BufWritePost,FileWritePost  *.asc  set nobin
cjs
  • 25,752
  • 9
  • 89
  • 101
  • Great, thanks. I'm going to go with this solution instead of the ftplugin based one, because this seems cleaner in the case where I have multiple extensions for files using the same language (like you have in your Haskell example). – Magnus Österlind May 21 '09 at 08:11
  • 1
    There is a little price to pay. The source commands (e.g. so ~/.vim/haskell.vim) will be executed every time you switch to such a buffer. – Fritz G. Mehner May 21 '09 at 08:55
  • 4
    This is not the correct solution. The correct solution consists in using ftplugins (no need to write and maintain the autocommands ourselves), and (very important) in using local settings. -> s#:set tabstop=#:setlocal tabstop=#. See fgm's answer. If your extension is not recognized as haskell, then update your filetypes base. Don't you want vim to apply the correct syntax highlighting to your files? – Luc Hermitte May 21 '09 at 10:43
  • Personally, no, I don't; I rather dislike syntax highlighting. (And it looks pretty silly in a language like Haskell that has so little syntax.) But I understand that this doesn't apply to most users. – cjs May 21 '09 at 10:57
2

I use the editor config plugin and add a .editorconfig file to all my projects - it will let you define different indentation settings for different projects using the same programming language which can be useful as often different projects in the same language have different coding standards.

You can see an example of the types of configuration you can set here: http://editorconfig.org/

Ben
  • 2,661
  • 28
  • 31
  • 1
    This is great because a number of other editors also support the same .editorconfig file (atom, sublime text, webstorm, visualstudio, etc etc), so it works well on a team or repository where people use all different flavors of editors. – Charlino Jul 27 '16 at 23:12