Introduction
Vim beginners tend to have some problems operating with tabulators and other non-printable characters. Here’s a quick tour on available options.
Showing non-printable characters
In Vim, you can toggle showing non-printable characters on and off using
set list!
. Characters used to represent non-printable characters are
not too pretty by default in Vim. Fortunately you can change it using
listchars
option. Here’s the value that I like to use:
set listchars=tab:▸\ ,eol:¬,nbsp:␣,trail:·
In order to enter those strange characters in Vim, you can use
ctrl-vuXXXX
(changing XXXX
to unicode hexadecimal code) while in
insert mode. Here are the codes for the characters I use:
␣
-ctrl-vu2423
·
-ctrl-vu00b7
▸
-ctrl-vu25b8
¬
-ctrl-vu00ac
If you only want to see one characters code, you can use ga
command.
It will show you the code of the character the cursor is on. It will
work on both printable and non-printable characters.
Expanding tabs to spaces
If you want to use spaces instead of tabulator characters (like I do),
set expandtab
option. If this option is set, Vim will use appropriate
number of spaces each time you try to insert tabulator character (note
that even though pressing noexpandtab
option.
If you want to force Vim to insert tabulator character even if
expandtab
is set (and not replace it with spaces), you can use
ctrl-v<TAB>
command while in insert mode. This can be useful in
Makefiles, for example.
Tabulator width
Vim uses 4 different options to control how tabulators are handled. I
already mentioned expandtab
boolean option. tabstop
option specifies
how many spaces tabulator character counts for, by default it’s 8. This
means that each tabulator will be separated by another by 8 spaces.
shiftwidth
is applied when <
and >
normal mode commands are used and
it specifies how many spaces should be inserted at the beginning of the
line. If noexpandtab
is set, Vim will try to use tabs instead of
spaces each time indentation can be represented with them. If it’s not
possible, it will mix tabs and spaces to ensure proper shift. To ensure
consistency, you generally should set shiftwidth
to be equal tabstop
.
softtabstop
, the last option, is disabled (set to 0) by default. You
can enable it by setting number of spaces that Vim uses each time you
enter (or remove) tabulator character in insert mode. It’s similar to
shiftwidth
in that Vim will try using tabulators if possible and
noexpandtab
. To ensure consistency, you generally should disable
softtabstop
or keep it equal to shiftwidth
and tabstop
. So why
ever enabling softtabstop
? For
So my best advice is to always keep tabstop = shiftwidth =
softtabstop
. Wile it’s possible to use any other combination in Vim, I
can’t imagine situation where this may be of much use.
Converting tabs to spaces in whole file
If you want to convert all tabulator characters to spaces with
expandtab
set, you can use :retab
command. You can also use
:retab!
to change spaces back to tabs is your noexpandtab
is on but
you have to be careful with that when you are editing some code as this
may brake your strings.
Setting preferences according to filetype
Some files requires you to use spaces instead of tabulators (like YAML)
for example, while others forces tabulators (Makefiles). I already
showed how to force inserting tab character even if expandtab
is on
but there’s easier way - use different settings for different file
types. To do this, use something like this in your vimrc
file:
if has("autocmd")
filetype on
autocmd FileType make setlocal ts=8 sts=8 sw=8 noexpandtab
autocmd FileType yaml setlocal ts=4 sts=4 sw=4 expandtab
endif