Thursday, April 5, 2012

Indent/unindent tip in vim

In vim, I do a fair amount of code refactoring.  As a result, I often find myself indenting and unindenting blocks of code (sometimes I'm cleaning up my own code, but often I'm cleaning code that has passed through many hands).

As you may already know, you can use shift-v  and then j and k to highlight lines of code in vim.  You may also already know that you can use > and < to indent and unindent a highlighted chunk of text by one tab.

The thing that always bothered me is that after I use >, the code is automatically un-highlighted.  So if I want to indent a chunk of code multiple times I have three options:

Solution 1:  Highlight the code with shift-v.  Then guess how many times I want to indent and then prefix my > with that number:  shift-v, j, j, j, 3, >
Problem 1:  I never guess right.  I'm always off by 1.

Solution 2:  Highlight the code with shift-v.  Indent once with >.  Then use gv to re-highlight the previous chunk. Then use > again.  Repeat until I have the code where I want it: shift-vjjj>, gv, >, gv, >
Problem 2: I never remember to use gv.  It's just not in my muscle memory.  I start re-highlighting, which clears the gv register... THEN I remember about gv.  Arrrg.

Solution 3:  Just give up and manually re-highlight with shift-v after doing a single indent: shift-vjjj,  >, k, k, k, shift-vjjj,  >, k, k, k, shift-vjjj,  >
Problem 3:  This is really inefficient adding tons of keystrokes.

Finally, I came up with this solution.  I added the following lines to my .vimrc:

This remaps > to do a > and then do a gv right away (and the same for <).  This gives me the benefit of solution 2 from above without me having to remember to use gv.  Doing this, I could accomplish the same task as above with a simple:

shift-v, j, j, j, >, >, >

The only catch is that you have to manually turn off highlighting when you're done with either another shift-v or an escape press.


  1. You could more simply use the '.' key to repeat the last change, it works for multiple presses, until your last change changes.

    You can therefore select your line to indent with shift-v, indent with > and then repeat the indent command by pressing . one or more times.

    Also, you can get Vim to automatically indent blocks of code by selecting a block and pressing the '=' key. This works quite well for most code which saves you the trouble of manually changing the indenting for all the lines. Sometimes it doesn't get it quite right, just because it's version of aethetics differs from yours, but sometimes the differences can actually indicate you've missed off a terminating character which can help whilst debugging.

    1. Thanks. That's a great tip and it works great. I will add that to my tool belt.