Fatih Arslan

My thoughts about Programming, Coffee, Bags and various other stuff

Navigation between functions and types in vim-go

Photo by https://unsplash.com/danist07

Photo by https://unsplash.com/danist07

I’ve introduced a new tool called motion in my previous post (I recommend to read it before you continue) and explained new features (such as text-objects) that are implemented on top of it.

Text-objects are great to modify and change the function. But we also might want to move around functions. Suppose there are several function declarations in the current file and you want to jump to them directly? There is a function that starts with “New…” but you don’t remember what it is? Or you quickly want to move to the next/previous function?

With the today’s vim-go release you’ll be easily answer all these questions! Let me first start with by moving to next/previous functions.

Text motion objects

Vim-go has two new text object motions:

]]   forward to next function declaration
[[   backward to previous function declaration

Now you can easily move forward to the next function by hitting ]] . If you want to move backwards just use the opposite: **[[ **. The best part is that its a motion object just like w for word, p for paragraphs, etc.. And you even can prefix it with a count, for example the following jumps to the third function from your cursor:


Or the following deletes everything until next function:


As you see it’s up to you how you combine these new motion objects. For me it’s now much more easier if I want to jump forth and back between two near functions. I don’t have to think anymore about _how many lines _I have to jump forward or where the function is. It just works. Here is a video that shows it in action:

Under the hood it uses motion. So you might ask how we find the next function declaration for a given offset? The first thing to remember is that Go’s parser is really fast. So if you parse a Go file to retrieve the AST, it’ll be instantaneously.

So what happens if you type ]] to move to the function declaration?:

Now as you see all these steps are executed so fast you don’t even notice it. Someone asked me if I use a cache for these intermediate results. Go is so fast that we don’t need any kind of cache between the editor and the tool. It just works.

Jump to function/type declarations

What about jumping to a function whose name you know already in a given file? Suppose the file itself is over 500 lines and you barely know where the function is declared. However you know the function very well. Or suppose you have a package that is spread over multiple files, wouldn’t it be cool if you could jump from one to another just by giving a function name?

This questions are now covered with the following new commands:

:GoDecls [file]
:GoDeclsDir [dir]

This currently depends on the excellent ctrlp.vim plugin (support for unite and co will implemented in the future too). It’s because ctrlp has a great UI that let us filter a list of items and then open the selection in the current buffer, vertical/horizontal or even in a new tab. The commands above are therefore only available if you installed ctrlp, if not they will not show up.

So how to they work?

It not only jumps to function declarations it also jumps to type declarations too! Here is a GIF that shows it in action:

:GoDecls and :GoDeclsDir in action

:GoDecls and :GoDeclsDir in action

As you see vim-go got much more powerful due the underlying tool (motion) and the implementation on top of it. It’s highly extendible and I’m looking forward to implementing even more features in the future (such as dealing with structs).

All these features are now available immediately. Go ahead and pull the latest changes from https://github.com/fatih/vim-go. If you find any bugs please open a new issue. As always, I’m more than happy to receive any kind of feedback.

If you have any questions or feedback, please feel free to share them with me on Twitter: @fatih