September 4, 2024

Vim - tabs

Everyone agrees. Tabs are evil.

When I began working with Haskell (and Python) which are whitespace sensitive (indentation sensitive) languages, I had to get a grip on vim and tabs. What I did was to decide to keep them out of my files entirely. Convert them to spaces as soon as possible and be done with it.

Make is an odd exception. Due to some ancient and foolish design choice, makefiles demand tabs as part of the syntax. But this can be dealt with.

The commands

All of this belongs in your .vimrc file.
In general these are vim variables that you use the "set" command to manipulate.

:set tabstop=8 (:set ts=8). This sets the width of a tab character.

:set expandtab (or noexpandtab). A boolean that indicates tabs should be replaced by spaces.

: set softtabstop=0. I set this to zero to turn this off altogether. It is only useful if you actually are allowing tabs to be present in files. You may have hard tabs at 8 and softtabs at 4, so that when you do tab keypresses in vim you get a motion of 4. But this has always led to tab hell with the languages I use, so I turn it off and forget that it exists.

: set shiftwidth=4. This controls the effect of the indentation commands you use in normal mode.

We also have an option called "smarttab". One fellow says: "smarttab is only meaningful if we have set "set expandtab" and softtabstop differs from shiftwidth. But normally it's not the case and we don't need smarttab.

What I do

"expandtab shiftwidth=4 tabstop=4 softtabstop=0". With expandtab on, I can use the < and > characters to fool with indentation. Backspace will just get rid of a single space (which is fine). If I turned on softtabstop, the backspace key would get rid of the pseudo-tabs, i.e. the proper number of spaces to maintain the tab illusion -- but I don't do this. If you did enable sts (softtabstop), you should make sure that shift width and soft tab stop are the same.

For make, I do this:

autocmd FileType make setlocal noexpandtab

Fixing files with tabs in them

I found that typing ":retab" made everything right (given my settings) when I began working with a file that actually contained tabs. Since I set expandtab, no file should ever escape from vim with tabs in it, except for a Makefile.


Have any comments? Questions? Drop me a line!

Tom's vim pages / tom@mmto.org