Vim’s indent guides are a visual aid that draws vertical lines in your code to represent indentation levels, making it much easier to track where blocks of code begin and end.

Let’s see it in action. Imagine this Python code:

def my_function(arg1, arg2):
    if arg1 > arg2:
        print("arg1 is greater")
        for i in range(arg1):
            print(i)
    else:
        print("arg2 is greater or equal")
        if arg2 > 100:
            print("arg2 is very large")

Without indent guides, just looking at the spaces can be a bit of a strain, especially in longer functions or nested structures.

Now, with a simple Vim configuration, we can add those visual lines. The most common way to achieve this is using the indentLine plugin, or by leveraging Vim’s built-in conceal feature with some clever settings. For simplicity and widespread adoption, let’s focus on the indentLine plugin.

Here’s how you’d typically install and configure indentLine using a plugin manager like vim-plug:

In your .vimrc (or init.vim for Neovim):

call plug#begin('~/.vim/plugged')
Plug 'Yggdroot/indentLine'
call plug#end()

After running :PlugInstall, you’ll need to enable it and customize its appearance. A basic enabling looks like this:

let g:indentLine_enabled = 1

This will immediately show vertical lines. But we can make them much more useful. indentLine can use different characters for different indentation levels, and it can be configured to only show guides for actual indentation, not just spaces that are part of a string or comment.

A more robust configuration might look like this:

let g:indentLine_enabled = 1
let g:indentLine_char = '¦'  " The character to use for the indent guide
let g:indentLine_color_term = 238 " Dark grey for terminal Vim
let g:indentLine_color_gui = '#606060' " Dark grey for GUI Vim
let g:indentLine_builtin_foldtype = 1 " Use Vim's foldtype for better detection
let g:indentLine_conceal_ladder = 1 " Conceal characters that are not part of indentation

The g:indentLine_char sets the visual character. ¦ (broken bar) is a popular choice because it’s distinct but not overly intrusive. The color settings (color_term and color_gui) ensure it blends well with your current color scheme. builtin_foldtype helps indentLine understand Vim’s internal folding mechanisms, which often correlate with indentation. conceal_ladder is key for avoiding false positives in strings or comments.

With these settings, our Python code now looks like this:

def my_function(arg1, arg2):
¦   if arg1 > arg2:
¦   ¦   print("arg1 is greater")
¦   ¦   for i in range(arg1):
¦   ¦   ¦   print(i)
¦   else:
¦   ¦   print("arg2 is greater or equal")
¦   ¦   if arg2 > 100:
¦   ¦   ¦   print("arg2 is very large")

The vertical lines clearly demarcate the scope of each if, else, and for block, making it instantly obvious where each block starts and ends. This is especially powerful in languages like Python, where indentation is syntax.

The mental model is simple: indentLine hooks into Vim’s buffer rendering and, for every character in a line, checks if it’s part of an indentation block. If it is, and the character is not a regular text character (like a space or tab that’s part of the indentation itself), it replaces that character with the configured indentLine_char. It uses Vim’s internal understanding of indentation (often derived from shiftwidth and tabstop) and, with conceal_ladder, intelligently avoids drawing lines within strings or comments.

A common point of confusion is why indent guides sometimes appear in places you don’t expect, like inside strings. This is usually because the conceal_ladder option isn’t enabled or because the plugin is misinterpreting the indentation. The conceal_ladder option is crucial; without it, indentLine might draw guides even for spaces within quoted strings if those spaces align with indentation levels. This is because the plugin’s default behavior is to draw a guide for any character that falls on an indentation column, and it needs to be told to conceal (hide) those guides if they fall within a "concealed" region like a string.

The next step is usually to explore how indentLine interacts with Vim’s built-in folding mechanisms to create even more powerful visual cues.

Want structured learning?

Take the full Vim course →