Archive | January 2019

Stuff in my vimrc: 03 Folds and why I don’t use them

Part three is going to be a bit different. Initially, this part was suppose to be about Vim Folds and about what I have in my vimrc to handle them. But there isn’t much related with folds in my file, and I don’t usually use them in my workflow. Because of this I though about skipping this part entirely.

But then it hit me, rather then skipping, why don’t I simply talk about why I don’t use them and what I do instead to orientate myself in a big file of code?

What Folds Are

In any project, you’ll find files which have a few dozens of functions, classes, structures, etc. It is not easy to get a mental overview of such files, since you have to scroll though several lines of code, sometimes passing by functions or classes which have over 100 lines of code, 7 levels of indentation, and obscure names.

Off course, one can always argue that if a file as such structures, then the code might need to be refactored. Be that as it may, such files are out there, and we have to maintain them.

A very common way to get such an overview is to fold the code, like in this image:

This is folds.c file in the Vim code that implements this feature. In it, all of the code of the functions is folded away and we only see their names and order within the file. We quickly get an overview of the content with little to no scrolling.

Such folding features are present in most (if not all) IDEs and in many editors. Vim has folding out of the box. It comes with a variety of key binds based on using the z key to open and close folds, and like in anything else, you need to specify a few settings before being able to use it.

To enable folding, I have the following:

let c_no_comment_fold = 1

" Function to start using folds, but only when I want
fu! StartFolds()
    set foldnestmax=1     " Only fold one level
    set foldmethod=indent " Use syntax to determine where to fold

nnoremap <silent> <leader>z :call StartFolds()<CR>

There is a constant declarations, a function, and a custom key bind.

The constant c_no_comment_fold is there to make Vim not fold C-like comment blocks. These are blocks like so:

 * This is a C comment block

Such syntax is present in languages such as C, C++, C#, Go, Java, CSS, and so many many others. It just so happens that when I have folded code, I simply like to have the comments still present. This is because if I’m folding, then that is because I’m trying to understand the code in a file, and having any comments helping me with that task is important.

So having a bulk of code away of view is important until I decide to open it explicitly. But having a comment block is always important.

Next, the function StartFolds. This function only executes when I press the custom key bind defined right bellow <leader>z. This function simply sets the two variables:

set foldnestmax=1     " Only fold one level
set foldmethod=indent " Use syntax to determine where to fold

About foldnestmax. Vim can fold in many levels of indentation. Think for example that you can fold a whole function, an if block inside a function, an if block inside another if block, and so on. I decided that it is enough to fold only one level, so I set that option.

About foldmethod. Vim can fold according to many rules. For example, it is possible to set manual markers between two lines, and have Vim fold in those lines. It is also possible to let Vim fold according to the current syntax. I have it set to indent. Like this, Vim picks indentation blocks to fold.

My current setup could be improved by having a function to disable folding. And now that I’m writing this post I’m starting to think that I would like to try having manual markers…

Tag Bar as Alternative

The key issue is getting orientated in a big file and knowing what is declared in it. I like to use a tags bar:

A bar such as this gives me the necessary overview. I can sort the bar according to different rules, scroll it, and select one item to have my view jump directly to the element in the file. Because this is jumping, I can also use the Go Back feature builtin in Vim. Basically, every time you jump within a file or to another file in Vim, it creates an internal stack of locations. You can then traverse that stack backwards to get back to a previous location.

I have a simple key bind to show or hide the bar which is <leader>t. I usually only bring the bar up when I have a single file in view, or at most a vertical split. Anything else and the screen becomes to cluttered.

The content of the tags bar is filled according to the tag information of Vim. I use the plugin You Complete Me that fills that tag information. Off course, any tag information will always depend on how the support for tagging that a language as. So when working with a common programming language, you will most probably have tag information.

In future posts, I’ll talk about semantic completion and the usage of these plugins in more detail.

<- Prev – 02 File ExtentionsNext – 04 Spelling and Natural Language ->