views:

523

answers:

5

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 plug-in (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?

A: 

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.

prestomation
The two languages I would most need this for would be Perl and Xml. I had come across that plugin before and was looking for something a little cleaner in appearance than the block highlight - like thin vertical lines.
mjn12
+4  A: 

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
Nikolay Frantsev
+3  A: 

This will show dots to indicate your indentation level as you type. The dots magically disappear as you leave the line.

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

E.g:

def test():
....print('indentation level 1')

Pretty cool huh?

Pierre-Antoine LaFayette
+3  A: 

Probably the most effective solution would be to "draw" indentation guides using match-highlighting. To understand how it helps, look at this example:

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

It highlights (using 'Search' group, it's possible to use any other, of course) the first, the fifth, the ninth (and it can be continued) virtual column occupied by space symbol preceding nothing but spaces from the beginning of line. So, this produce four-spaces indentation lines highlighting for three levels in deep!

To generalize this idea it remains only to generate pattern like that mentioned above according to the current buffer textwidth and shiftwidth (to handle deeper indent levels and proper indent width). This task could be simply automated using the function shown below.

function! IndentGuides()
    let pos = range(1, &l:textwidth, &l:shiftwidth)
    call map(pos, '"\\%" . v:val . "v"')
    let pat = '\%(\_^\s*\)\@<=\%(' . join(pos, '\|') . '\)\s'
    call matchadd('Search', pat)
endfunction

So, here we are. Every time you need indentation guides in a buffer, :call IndentGuides() create it for you. Of course, you could change highlight group (may be, create a special one for indentation lines only), setup a handy mapping for that and/or call it from autocmd for some file types.

ib
A: 

From Nikolay's answer

" display indentation guides

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

Using gVim on XP I had to escape the pipe character in my vimrc as in

tab:\|-

Or else I got E474: Invalid argument: lcs=tab:

Mike Walsh