Could someone explain to me in simple terms the easiest way to change the indentation behavior of Vim based on the file type? For instance, if I open a Python file it should indent with 2 spaces, but if I open a Powershell script it should use 4 spaces.
11 Answers
You can add .vim
files to be executed whenever vim switches to a particular filetype.
For example, I have a file ~/.vim/after/ftplugin/html.vim
with this contents:
setlocal shiftwidth=2
setlocal tabstop=2
Which causes vim to use tabs with a width of 2 characters for indenting (the noexpandtab
option is set globally elsewhere in my configuration).
This is described here: http://vimdoc.sourceforge.net/htmldoc/usr_05.html#05.4, scroll down to the section on filetype plugins.
Use ftplugins or autocommands to set options.
ftplugin
In ~/.vim/ftplugin/python.vim:
setlocal shiftwidth=2 softtabstop=2 expandtab
And don't forget to turn them on in ~/.vimrc
:
filetype plugin indent on
(:h ftplugin
for more information)
autocommand
In ~/.vimrc
:
autocmd FileType python setlocal shiftwidth=2 softtabstop=2 expandtab
You can replace any of the long commands or settings with their short versions:autocmd
: au
setlocal
: setl
shiftwidth
: sw
tabstop
: ts
softtabstop
: sts
expandtab
: et
I would also suggest learning the difference between tabstop
and softtabstop
. A lot of people don't know about softtabstop
.
edit your ~/.vimrc
, and add different file types for different indents,e.g. I want html/rb
indent for 2 spaces, and js/coffee
files indent for 4 spaces:
" by default, the indent is 2 spaces.
set shiftwidth=2
set softtabstop=2
set tabstop=2
" for html/rb files, 2 spaces
autocmd Filetype html setlocal ts=2 sw=2 expandtab
autocmd Filetype ruby setlocal ts=2 sw=2 expandtab
" for js/coffee/jade files, 4 spaces
autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype coffeescript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype jade setlocal ts=4 sw=4 sts=0 expandtab
This might be known by most of us, but anyway (I was puzzled my first time):
Doing :set et
(:set
expandtabs) does not change the tabs already existing in the file, one has to do :retab
.
For example:
:set et
:retab
and the tabs in the file are replaced by enough spaces. To have tabs back simply do:
:set noet
:retab
Today, you could try editorconfig, there is also a vim plugin for it. With this, you are able not only change indentation size in vim, but in many other editors, keep consistent coding styles.
Below is a simple editorconfig, as you can see, the python files will have 4 spaces for indentation, and pug template files will only have 2.
# 4 space indentation for python files
[*.py]
indent_style = space
indent_size = 4
# 2 space indentation for pug templates
[*.pug]
indent_size = 2
For those using autocmd
, it is a best practice to group those together. If a grouping is related to file-type detection, you might have something like this:
augroup filetype_c
autocmd!
:autocmd FileType c setlocal tabstop=2 shiftwidth=2 softtabstop=2 expandtab
:autocmd FileType c nnoremap <buffer> <localleader>c I/*<space><esc><s-a><space>*/<esc>
augroup end
Groupings help keep the .vimrc
organized especially once a filetype has multiple rules associated with it. In the above example, a comment shortcut specific to .c files is defined.
The initial call to autocmd!
tells vim to delete any previously defined autocommands in said grouping. This will prevent duplicate definition if .vimrc
is sourced again. See the :help augroup
for more info.
While you can configure Vim's indentation just fine using the indent plugin or manually using the settings, I recommend using a python script called Vindect that automatically sets the relevant settings for you when you open a python file. Use this tip to make using Vindect even more effective. When I first started editing python files created by others with various indentation styles (tab vs space and number of spaces), it was incredibly frustrating. But Vindect along with this indent file
Also recommend:
I use a utility that I wrote in C called autotab
. It analyzes the first few thousand lines of a file which you load and determines values for the Vim parameters shiftwidth
, tabstop
and expandtab
.
This is compiled using, for instance, gcc -O autotab.c -o autotab
. Instructions for integrating with Vim are in the comment header at the top.
Autotab is fairly clever, but can get confused from time to time, in particular by that have been inconsistently maintained using different indentation styles.
If a file evidently uses tabs, or a combination of tabs and spaces, for indentation, Autotab will figure out what tab size is being used by considering factors like alignment of internal elements across successive lines, such as comments.
It works for a variety of programming languages, and is forgiving for "out of band" elements which do not obey indentation increments, such as C preprocessing directives, C statement labels, not to mention the obvious blank lines.