Tuesday, October 7, 2008

Vim Code Folding

This is the sixth post in my series on using Vim to do C# development. You can read the introduction into why someone might want to do that here.

Visual Studio has a feature called "Outlining" which automatically allows you to collapse and expand regions, comments, methods, classes, namespaces, using statement blocks, etc. Ctrl+M, Ctrl+M will expand and collapse the block that your cursor is in. Ctrl+M, Ctrl+O will collapse all methods and summary comments (but not classes and namespaces).

Vim has this same ability built in but calls it Folding. The difference is simply that it has to be turned on if you want it, and that it doesn't understand your code as well as Visual Studio does (though it can be taught!).

In Vim, there are a number of different ways that folding can be done: syntax based, indent based, marker based, and manual. Syntax based looks for folding to be defined in the syntax file for the language being edited. Indent based folds lines that are at the same indent level. Marker based looks for a given character sequence and folders everything between those characters. Manual allows you to define where the folds should be.

I like to use the Syntax folding that's defined in the default Vim C# syntax file. This will fold #region ... #endregion blocks.

To make sure this is always on when I'm editing C# files I added the following to my vimrc:
if !exists("autocommands_loaded")
let autocommands_loaded = 1

" setup folding
autocmd BufNewFile,BufRead *.cs set foldmethod=syntax
endif

Note: if you've setup an autocmd for C# building as in my earlier post make sure you use the same if !exists()... block.

The following commands are used to open and close folds:
zo - open fold under cursor
zc - close fold under cursor
zR - open all folds
zM - close all folds

You can remember the "z" by thinking of those old accordion reams of paper where each sheet was connected to the next and imagining it from the side as you lift and lower the top sheet. From that profile the paper will appear to form a "z" as you fold and unfold it.

See :help fold.txt for more details.

2 comments:

Barnabas said...

Thanks for all of these posts. I have just started using Vim and I did all my work in Visual Studio up until this point.

This works great to get regions to fold. However I also enjoy folding brackets. Is there a way to do both at the same time?

Kevin Berridge said...

Thanks for the comment!

I don't think there is any way to have Vim use two folding modes at the same time. But I asked on the Vim IRC channel and was directed to this: http://pastebin.com/md0bd305

Basically, what you can do is define your folding brackets as syntax elements, like what a vim syntax file does. To get this code to execute you'll have to either put it in a file in Vim's "after" directory, or define an autocommand in your vimrc.

With this, the syntax fold mode should now fold {{{ just like marker mode. But don't hold me to it, I haven't tried it...