I should really write a blog post about this so I don’t forget. - Me, recently
Vim has a lot of indentation settings, and this can cause a lot of headaches. There are guides about this, but I thought it proper to give a list, explain them, and then describe some problems I have had and how to fix them.
Basic Settings
Choose Tabs or Spaces
expandtab
- This option lets you insert spaces when pressing Tab. This is the option that you are likely looking for when getting into Vim for the first time!
-
set expandtab
will insert spaces instead of a Tab character. You can still manually insert a Tab character usingCTRL-V<Tab>
. -
set noexpandtab
will insert a Tab character instead of spaces (this is the default setting for vim).
Settings that effect Tabs
tabstop
- This is the number of spaces that a <Tab>
(the Tab key) counts for. So, if you press the Tab key, it will move the cursor X spaces. However, these are not actual spaces. It is still the Tab character, this just tells Vim how many spaces a Tab is equal to.
set tabstop=8
will move the cursor equivalent to 8 spaces.
Settings that effect Tabs and Spaces
softtabstop
- Number of spaces that a <Tab>
counts for while performing editing operations, like inserting a <Tab>
or using <BS>
.
set softtabstop=2
will move the cursor back two spaces when using<BS>
(backspace). Many editors have this feature set to whatever number of spaces you have set for that file. It’s set separately in Vim.
shiftwidth
- This is the number of spaces to use for each step of (auto)indent. It is used for cindent
, >>
, <<
, etc. If set to 0
, the value of tabstop
will be used. Note that without set expandtab
, the Tab character will still be used.
set shiftwidth=4
will move the cursor forward 4 spaces from the last indent when pressing<Enter>
after declaring a function in a programming language (like C or C++).
Hmm,
softtabstop
andshiftwidth
seem similar! How are they different?
I’m glad you asked! softtabstop
is like shiftwidth
, but is for any editing operation. shiftwidth
is just for (auto)indents.
Okay, so what about auto indentation?
I’m getting there.
Auto Indentation
There are two types of auto indentation settings for Vim: manual and plugin / filetype.
Manual Settings
autoindent
- Copies the indentation of the previous line.
set autoindent
if the line I am on has an indent of 2, when I press<Enter>
, the next line will also have an indent of 2.
smartindent
- Automatically inserts one extra level of indentation in some cases, and works for C-like files.
cindent
- Enables automatic indenting according to the C programming language indentation rules. This is good for many programming languages as they are similar to how C works.
Generally,
smartindent
orcindent
should only be set manually if you’re not satisfied with how file type based indentation works - vim.fandom.com
Plugin / Filetype Settings
Most IDEs and editors update indentation settings on the fly, and Vim is no exception, but you must enable this feature.
filetype plugin indent on
- This command will use indentation scripts located in the indent
folder of your Vim installation. Notably, many plugin managers enable this by default (vim-plug is one such example).
Here’s where things get tricky. You need to understand that these indentation scripts are not always perfect. You can file bug reports or try to help fix them if you’re up to it! Typically, they work pretty well.
These scripts can set options for Vim for specific file types. So if you enable this setting, a .c
file will have cindent
enabled for it. Cool!
Okay, I have auto indentation working, but the default spaces aren’t what I want.
Onward!
Local File Type Settings
You can place default settings in $MY_VIM_CONF/after/ftplugin/some_filetype.vim
.
For example, if I wanted 2 spaces for Javascript, I can make ~/.vim/after/javascript.vim
and inside I can write:
" not needed for javascript if the filetype plugin is on
setlocal expandtab
setlocal softtabstop=2
setlocal shiftwidth=2
Editorconfig
Indentation is complicated in Vim. It makes sense because it’s so customizable, but I think many people just want to rock some settings for a project and forget about it.
You can use a .editorconfig
file and the editorconfig-vim plugin to do this. You’ll need to learn how to write .editorconfig
files, but it’s not complicated. You’ll also need one for each project you want to use specific settings for.
Neovim and Treesitter
One last thing that I’m sure people will run into is using Treesitter with Neovim. This was my setup for awhile, and I ended up switching back to Vim because of how complicated things got (and I just got tired of Lua).
Treesitter in Neovim is still experimental, and rightly so. I often had many settings just completely broken. This involved turning off various indentation settings, sometimes with Neovim, sometimes with the filetype plugin script, sometimes just regular settings. Then you can’t use the specific settings from the filetype script because you need that disabled to use Treesitter…it’s kind of a mess.
I would recommend just turning off indents altogether in Treesitter, but you will likely still experience some issues and possibly consider switching back to plain ole’ Vim.