Is it possible to display indentation guides in Vim?

Viewed 55585

I'm a longtime Vim user (3 or 4 years) who has recently started dealing with some deeply nested code. This code is indented with spaces, not tabs. I would like some clean and non-distracting indication of indentation to help with keeping track of which block of code I'm in when I'm looking at something many levels deep.

:set list 

only displays tab and endline characters. I have found one plugin (can't seem to dig it up at the moment) that will highlight each indentation level in progressively darker colors but this is visually unappealing. Ideally I would like to see thin vertical lines at each indentation level. Many new-fangled editors have this functionality but I'm not willing to give up on Vim just yet.

Does anyone know how this can be achieved?

7 Answers

This answer is a bit late to the party and also a shameless plug. :)

Regardless, try my Indent-Guides.vim plugin. It was created to scratch my own itch regarding the lack of indent guides in vim. I got fed-up waiting for someone else to come along and build it, so I just did it myself.

Features:

  • Can detect both tab and space indent styles.
  • Automatically inspects your colorscheme and picks appropriate colors (gVim only).
  • Will highlight indent levels with alternating colors.
  • Full support for gVim and basic support for Terminal Vim.
  • Seems to work on Windows gVim 7.3 (haven't done any extensive tests though).
  • Customizable size for indent guides, eg. skinny guides (soft-tabs only).
  • Customizable start indent level.

Here’s a few screenshots of the plugin in action: put your mouse here and click.

You might use tabs to display indentation guides and remove tabs before saving file:

" use 4 spaces for tabs
set tabstop=4 softtabstop=4 shiftwidth=4

" display indentation guides
set list listchars=tab:❘-,trail:·,extends:»,precedes:«,nbsp:×

" convert spaces to tabs when reading file
autocmd! bufreadpost * set noexpandtab | retab! 4

" convert tabs to spaces before writing file
autocmd! bufwritepre * set expandtab | retab! 4

" convert spaces to tabs after writing file (to show guides again)
autocmd! bufwritepost * set noexpandtab | retab! 4

The following command will configure Vim to show dots to indicate the indentation level as you type. The dots magically disappear when the cursor leaves the line:

:set list listchars=tab:»-,trail:·,extends:»,precedes:«

Probably the most effective solution would be to “draw” indentation guides using match-highlighting. To understand how it may be useful, take a look at the following example:

:match Search /\%(\_^\s*\)\@<=\%(\%1v\|\%5v\|\%9v\)\s/

It highlights—using the Search highlighting group; any other group can, of course, be used—the first, the fifth, and the ninth (it can be continued) virtual columns occupied by the space character preceding nothing but whitespace from the beginning of line. Hence, this produces highlighting for four-space indentation that is at most three levels deep.

The only thing remaining to generalize this idea is a procedure generating a pattern similar to the one above, according to the current buffer’s textwidth and shiftwidth settings, in order to handle deeper indent levels and use the actual indentation width. This task can be simply automated as shown in the function below.

function! ToggleIndentGuides()
    if exists('b:indent_guides')
        call matchdelete(b:indent_guides)
        unlet b:indent_guides
    else
        let pos = range(1, &l:textwidth, &l:shiftwidth)
        call map(pos, '"\\%" . v:val . "v"')
        let pat = '\%(\_^\s*\)\@<=\%(' . join(pos, '\|') . '\)\s'
        let b:indent_guides = matchadd('CursorLine', pat)
    endif
endfunction

Whenever indentation guides are necessary in the current buffer, it can be switched on via :call ToggleIndentGuides(). Of course, one can change the highlighting group (or even create a dedicated one for using with indentation guides), setup a handy mapping for that, and call it from an autocmd for some file types.

For an example, see the indentation guides highlighting configuration from my .vimrc file at https://gist.github.com/734422, which implements a slightly extended version of the above approach.

Try out this VIM plugin BlockHL It color codes the indentation of each successive level differently.

EDIT:What lanaguge are you using? This plugin is for C-style languages.

Related