53

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?

ib.
  • 27,830
  • 11
  • 80
  • 100
mjn12
  • 1,853
  • 3
  • 19
  • 27

7 Answers7

73

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.

ib.
  • 27,830
  • 11
  • 80
  • 100
Nate K
  • 1,121
  • 8
  • 5
  • 3
    Has anyone got this to work on a non Windows based machine? I can't get it to load, whether via Pathogen or not, and whether vim or gvim. Even the help files are not being loaded – puk Feb 21 '12 at 23:08
  • 1
    @puk: Works fine for me using MacVim (Vim 7.3) and Pathogen. – Gabe Hollombe Feb 29 '12 at 14:40
  • Do you happen to still work on that? Personally, I like the indentation guides of Notepad++, and I'd like to see gVim do that as well... – polemon Jun 27 '12 at 19:06
  • 9
    I had to add `let g:indent_guides_enable_on_vim_startup=1` to my .vimrc to enable this. (I couldn't get the help files to load, but the plugin worked fine after adding this line. – daviewales Apr 20 '13 at 15:41
  • Great plugin, but the only problem is when I try to copy text from the terminal using mouse, the indent char (|) is also copied. – ospider Dec 28 '16 at 03:33
37

If you indent code with spaces, you can try my plugin: https://github.com/Yggdroot/indentLine, it displays thin vertical lines but not thick vertical lines as the above answers mentions. If you indent code with tab, just :set list lcs=tab:\|\ (here is a space)

hochl
  • 12,524
  • 10
  • 53
  • 87
Yggdroot
  • 499
  • 4
  • 6
  • 7
    You need to disclose that it's your project. And your last answer was just a link and thus pretty useless. – ThiefMaster Dec 06 '12 at 10:35
  • Add highlighting the active block indent guides ! :D Like in Sublime Text and in Notepad++. – trusktr Apr 15 '13 at 02:34
  • 9
    @ThiefMaster Who cares if he didn't disclose it's his project? This is a valid answer. It's possible to have indentation quides (using *his* plugin), but it's free and open source.... so who cares if he doesn't disclose it's his?? He provided a solution. – trusktr Apr 15 '13 at 02:35
  • 4
    @ThiefMaster Would you have liked it better if he just literally pasted his code *inside* the answer? – trusktr Apr 15 '13 at 02:37
  • 6
    @trusktr: Because the majority of the Stack Overflow community frowns upon undisclosed self-promotion and answers that consist of just a link! If you have a problem with that, post on [meta]. – ThiefMaster Apr 15 '13 at 06:20
  • 1
    @ThiefMaster got any reference for the "majority" claim? – ravi Aug 17 '14 at 02:43
  • 1
    I frown upon it – Kvass Jan 08 '17 at 02:04
  • 2
    I'm several years late for the discussion above, but for the record, undisclosed affiliation [can be considered spam](https://stackoverflow.com/help/promotion). And yes, advertising a free and open-source project can still be spam - it being free and open-source doesn't automatically make it not spam, so yes, disclosing affiliation does matter. And to be abundantly clear, I'm not arguing that this answer is a problem as it stands right now – Zoe Apr 05 '21 at 17:39
  • @trusktr, I would prefer he pasted his code, so I can read the method and implement what I want from it. I can also follow the link to find the code but sometimes links fail, and sometimes I'm reading the SO article from behind a corporate firewall that doesn't allow all links. – NeilG May 26 '23 at 07:46
  • Hi @ZoestandswithUkraine, what is the principle behind disclosing affiliations, can you articulate? Something to do with transparency, fairness and eliminating spam and other pollution of the SO technical space? And how does political campaigning fit into those principles? Politics is so often mixed up in false narratives and misinformation for vested interests that I think one can say politics *always* consists of lies. It's almost part of the definition, along with "hypocrisy", which also seems to be a fundamental part of politics. Does SO have any rules about politics? – NeilG May 26 '23 at 07:51
30

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
ib.
  • 27,830
  • 11
  • 80
  • 100
  • 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 Aug 05 '10 at 06:04
18

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:«
ib.
  • 27,830
  • 11
  • 80
  • 100
Pierre-Antoine LaFayette
  • 24,222
  • 8
  • 54
  • 58
17

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.

ib.
  • 27,830
  • 11
  • 80
  • 100
  • This works well, but is it possible to display as more of a Sublime Text style vertical line every 4 spaces? – seagoj Feb 28 '14 at 21:39
  • @seagoj: Unfortunately, it is not possible to draw actual graphical lines even in GVim. The closest approximation is to highlight columns of spaces every `shiftwidth` positions, which is exactly what the solution proposed here does. – ib. Mar 01 '14 at 08:07
  • @nikolay-fransev's solution was basically what I was looking for. – seagoj Mar 01 '14 at 21:09
  • This is cool, but I'd love to know how to change from an _ in the indent column to some other character. – Mnebuerquo Jan 22 '18 at 13:56
  • @Mnebuerquo: You can fully customize it to your liking by either using a dedicated highlighting group in the `matchadd()` call above, or by keeping the `CursorLine` group there and customizing its appearance with the `:highlight` command. See `:help :highlight` and `:help highlight-groups`. – ib. Feb 20 '20 at 23:55
1

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
  • 7,225
  • 3
  • 39
  • 37
  • 1
    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 Jan 28 '10 at 22:17
0

use the Indent-Guides.vim plugin, and toggle use ig whenever you need it. Sometimes it could be annoying though :)

kevin
  • 1,107
  • 1
  • 13
  • 17