Vim indenting guide

Indenting system of Vim is powerful but also complicated and always a pain for beginners. I try to explain it in a post to save your time reading the manual

Preparation

Distinguish Tab and Space

In Vim, both tab and space character are displayed as spaces. To distinguish them, use

set list listchars=tab:\|\-

This makes vim to display tab as |--- rather than multiple spaces

View Vim Setting Value

:set setting?

This command gets the value of setting at Vim run time

and

:verbose set setting?

can let you see where setting is set

Hard Tab and Soft Tab

In Vim, a hard tab is a tab character and a soft tab means those chracters inserted when you press the Tab button on your keyboard(in insert mode, of course).

Yes, your inputed "tab" is not necessarily an actual tab character. The size of a hard tab and a soft tab is tabstop and softtabstop respectively.

An Indentation

To indent a line, you either use auto indent, let Vim indents for you, or you manually indents, using soft tabs and spaces

The size of an indentation created by auto indent is shiftwidth, which is also used by < and > to shift lines

Content of an Auto Indent Indentation

I want to point it out first because I think it's crucial in understanding the whole indenting system. The truth is that in Vim, an indentation may consists of hard tabs and spaces at the same time.

Mix of tabs and spaces sounds strange, but it exists in legacy code, see this issue

So, we alreadly know the size of an indentation created by auto indent is shiftwidth, how to decide the number of tabs and spaces? The solution Vim use is inserting as much hard tabs as possible and inserting spaces for the remainder

For example, if shiftwidth=8 tabstop=4, you get 2 hard tabs, but when shiftwidth becomes 7, you get 1 hard tab and 3 spaces

Auto Indent

auto indent automatically add and remove indentation

In Vim, there are four methods of auto indent

  • autoindent: just copy the indentation of previous line
  • cindent: c-style indent
  • smartindent: more strict than cindent, can also be used for other languages
  • indentexpr: Evaluates an expression to compute the indent of a line

Filetype Indent

If you set autoindent in your .vimrc and test editing a .c file and an empty file, you'll find out that cindent is set when editing .c file while it's not when editing empty file, this is the result of filetype indent

What filetype indent does is that it detects the filetype and set the auto indent method respectively, it's part of filetype indent which also includes filetype detection and filetype plugin

use :verbose set cindent? show

  cindent
        Last set from /usr/share/vim/vim82/indent/c.vim line 13

indicating that it's not set by a user

So, because of filetype indent, generally you don't have to set auto indent method yourself

Manually Indent

You can use soft tabs and spaces to manually indents, most people just use one single soft tab

Content of a soft tab

A soft tab is softtabstop size long, how many spaces and tabs it use? Maybe you already guessed it, soft tab use the same method as auto indent indentation, inserting as much hard tabs as possible and then spaces

Consistency between Manually Indent and Auto Indent

Imagine you are on a empty new line with an indentation created by auto indent, when you exit to normal mode, this indentation will be removed automatically and you have to add it back manually, usually using a soft tab, it will be a disaster if the result is different

To achieve consistency, you can set softtabstop to be the same as shiftwidth, we already know that they use the same method to determine the actual content, so the result is granted to be the same.

Or you can use smarttab, it lets a softtabstop become shiftwidth at the beginning of a line

Expandtab

Finally, if you don't want hard tab, just set expandtab and all hard tabs in soft tab and indentation is converted to spaces of the same size

Examples

n spaces as indentation

set shiftwidth=n
set softtabstop=n
set expandtab

A size n hard tab as indentation

set shiftwidth=n
set softtabstop=n
set tabstop=n

n spaces as indentaion and soft tab is a hard tab of size m

" n < m
set smarttab
set shiftwidth=n
set softtabstop=m
set tabstop=m

Reference

  • h indent.txt about auto indent
  • h filetype.txt about filetype
  • h setting about settings

Want to leave a comment? Please email me