How to set up Vim for Go Development

One of the major reasons I love programming in Go is that I can do it in any IDE or editor I want, including my favourite Vim editor.

Unlike Java, for example, which is highly coupled to IntelliJ or Eclipse, Go is much more lightweight and the tools you use with it can be integrated with any editor.

In this guide, I will help you setup your Vim as a fully-fledged Go IDE, including the plugins you need to install but also setting up the important options & mappings which you'll use daily.


You'll need to have Go installed & your Go environment setup, namely your $GOPATH and related subdirectories - /bin /pkg /src.

You'll also need to use nvim instead of vim or have your vim updated to version 8+.

The Main Vim plugin for Go

One of the only plugins you need for Go is called vim-go. It aggregates all the tools you need to get started with Go development.

To install it via pathogen:

git clone ~/.vim/bundle

Other installation options.

After you've installed it, you can customise it using these options which are highly opinionated, but work best for me:

" disable all linters as that is taken care of by coc.nvim
let g:go_diagnostics_enabled = 0
let g:go_metalinter_enabled = []

" don't jump to errors after metalinter is invoked
let g:go_jump_to_error = 0

" run go imports on file save
let g:go_fmt_command = "goimports"

" automatically highlight variable your cursor is on
let g:go_auto_sameids = 0

For syntax highlighting, use these options:

let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_operators = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_build_constraints = 1
let g:go_highlight_generate_tags = 1

Finally, install all the required go tools by opening vim and running:


coc.nvim - Autocompletion & linting

In the past, I've relied on YouCompleteMe for auto-completion or vim-go's native integration with vim for auto-completion & ALE for linting/static code analysis.

Nowadays, I prefer using coc.nvim and its plugins to do all that as I've found it to be more reliable than all of those tools.

For installation instructions, follow the Quick Start guide.

After you've installed it, run this command to install the necessary coc extension for Go:

vim -c 'CocInstall -sync coc-go coc-html coc-css coc-json|q'

The html/css/json extensions are optional but who doesn't deal with those nowadays. You'd probably need them at some point.

Afterwards, open vim & type :CocConfig to open coc's configuration file. These are my opinionated settings, stripped from the non-go related settings:

  "suggest.noselect": false,
  "diagnostic.errorSign": "✘",
  "diagnostic.warningSign": "!",
  "diagnostic.infoSign": "?",
  "diagnostic.checkCurrentLine": true,
  "coc.preferences.formatOnSaveFiletypes": [
  "coc.preferences.hoverTarget": "float",
  "languageserver": {
    "golang": {
      "command": "gopls",
      "rootPatterns": ["go.mod"],
      "filetypes": ["go"]
  "go.goplsOptions": {
    "staticcheck": true

For all auxiliary coc settings, add these settings to your .vimrc.

Mappings For The Most Useful Commands

Having great tools is not enough. You need to know how to use them. Hence, it is best to customize some of the mappings which vim-go and coc provide you so that you're more effective when dealing with Go code.

Here are the mappings I use most often and the way I've configured them:

Manage unit tests in the current file

I've mapped running all the tests in the current file to <leader>-t which translates to \ + t on my Mac & Linux.

autocmd BufEnter *.go nmap <leader>t  <Plug>(go-test)

I've also mapped \ + tt to run the current test function only, instead of running all of them:

autocmd BufEnter *.go nmap <leader>tt <Plug>(go-test-func)

Finally, I use \ + c to toggle the coverage profile for the current file I'm in:

autocmd BufEnter *.go nmap <leader>c  <Plug>(go-coverage-toggle)

Inspect a Go Codebase

Show the function signature for a given routine with \ + i:

autocmd BufEnter *.go nmap <leader>i  <Plug>(go-info)

Show the interfaces a type implements with \ + ii:

autocmd BufEnter *.go nmap <leader>ii  <Plug>(go-implements)

Describe the definition of a given type with \ + ci:

autocmd BufEnter *.go nmap <leader>ci  <Plug>(go-describe)

See the callers of a given function with \ + cc:

autocmd BufEnter *.go nmap <leader>cc  <Plug>(go-callers)

Find all references of a given type/function in the codebase with \ + cr:

nmap <leader>cr <Plug>(coc-references)

Go to definition/Go back with Ctrl+d and Ctrl+a:

nmap <C-a> <C-o>
nmap <C-d> <Plug>(coc-definition)

Refactor Go Code

Not many options here, but there's renaming the symbol your cursor is on with \ + r:

nmap <leader>r <Plug>(coc-rename)

Occasional Maintenance of Tooling

To update all Go tools, run this from vim:


And updating all coc plugins:


To upgrade vim-go or coc.nvim, delete the folders from ~/.vim/bundle and git clone the repos again.

Setup The Cool gruvbox Theme (Optional)

Install gruvbox using pathogen:

git clone ~/.vim/bundle

Enable it in your .vimrc with some opinionated extra options:

colorscheme gruvbox
autocmd ColorScheme * highlight CocErrorFloat guifg=#ffffff
autocmd ColorScheme * highlight CocInfoFloat guifg=#ffffff
autocmd ColorScheme * highlight CocWarningFloat guifg=#ffffff
autocmd ColorScheme * highlight SignColumn guibg=#adadad

Want to see how it looks?

Setup tmux For Terminal Multiplexing (Optional)

If you want to manage multiple terminal tabs in the same window, use tmux (See my how to guide):

This is one of the most useful tools I have setup because it allows me to do my code editing in vim and manage all sorts of other terminal-related tasks in separate tabs all inside the same window.


And that's everything I use for my daily Go programming.

This setup has worked extremely well for me and have in mind that I'm also dealing with Uber's huge Go Monorepo, where I've been able to integrate my vim environment seamlessly (with some extra settings which you probably won't need.

If you want to see my entire vim development environment, check out all my dotfiles and default-setups repos, which include my full setup, including external programs, the terminal, vim, tmux, colorschemes, etc.

Happy Gophing!

Check out some of my other Go series:
Integrating your Go Service with ELK
gRPC With Go Crash Course

Incremental search in vim

incremental search in vim

There is a slight, but obnoxious difference in how the default search works in vim against the way it works in other IDEs.

In vim, whenever you click the / (forward slash) you start writing a word you want to find in the current file. The problem is that you have to write the whole word and click enter before you start seeing the results.

This can work fine and you can cope with it most of the times, but it can start getting in the way pretty quickly once you start searching for longer words or phrases, whose exact identifier you can get wrong pretty easily. At that point, you have to start all over again with the search and be very careful about writing the keywords precisely.

The way search works in IDEs is that it starts showing results while you're typing the keyword. This way, you can:

  • Get to the word you need before you even write the whole keyword
  • Detect a mistake in your term before you're finished

This feature is called incremental search and can be very handy.

Today, I want to show you how to get it in your vim editor.

This article is part of the sequence  Boost Your VIM where I share my favorite vim plugins and tools which can greatly optimize your productivity and make you a better keystroke ninja.

Continue Reading

Pathogen – The Best Plugin Manager for vim

Continuing the Boost your VIM series with the next neat vim plugin - pathogen! Last time, I showed you one of my favorite bash utilities (which happens to work so wonderfully with vim) - tmux. This time, I will introduce you to my weapon of choice when it comes to plugin managers. It's called pathogen. This is the best and yet simplest plugin manager there is. There are others, like Vundle, which I've tried in the past but none can beat pathogen's simplicity. It's so simple (in fact, the total source code is ~250 lines), that this will be a pretty simple post as well. So, if you're ready to hack your VIM with some neat plugins, start with this one and make your life easier.
Continue Reading

tmux – A Terminal Multiplexer

Last time, I wrote about why I think everyone should try using a bare bones text editor like vim at least for a while. After such an experience, some might give up on it, while others might want to switch to vim full-time. For the latter - congratulations! But inevitably, a problem will occur with this approach, especially if you are working on a big project - using bare bones vim for big projects is quite unproductive compared to IDEs. I used to use vim on my hobby side projects and it did a great job, but once I tried using it on a project with a large code base and several different build variants, things started to get messy and I preferred using the IDE. Some of you might disagree with me, I have seen people prefer sticking solely to bare bones vim. But in my experience, apart from the text editing boost it gives you due to its awesome user interface, all the auxiliary tools you need to maintain a big project are invaluable and not easily available from a bare bones vim. So, determined to amend that, I started exploring many different tools and plugins to enable my vim to challenge the productivity my IDE provides. In this new series of articles, I will share my favorite tools which help me keep myself productive everyday by using vim. In the first one, the topic is my all-time favorite vim add-on - tmux.

This article is part of the sequence  Boost Your VIM where I share my favorite vim plugins and tools which can greatly optimize your productivity and make you a better keystroke ninja.

Continue Reading

How can vim make you a better developer

The first time I encountered vim was during a Linux System Administrator course I attended a while ago. Didn't really know much about Linux back then. It just sounded quite fancy. During the course, the lecturer often typed in that 3 word command vim and edited some stuff. "Gee, that looks cool", I thought! So, determined to look cool myself, I got back home, opened a terminal, typed in the magic words and voila! - I was inside vim. So, with a great wish to write my first Hello World txt file in vim, I started hitting keys on my keyboard. And nothing was happening. Some strange beeps started coming out of nowhere and I felt utterly frustrated! So, my goal quickly shifted from typing anything, to exiting vim. Yeah, you probably know what follows. A key-hitting berserk got me while doing everything I can to exit vim. Finally, after failing my first clash with the editor, I was so thankful to have the X key at the top right of my terminal emulator. Now, this story should sound pretty familiar if you ever tried using vim. Well, eventually you learn how to exit it, and you learn how to type in symbols. But there is so much more to it. The endless sets of key-combos can leave you wondering what the heck you did after accidentally hitting a key. Nowadays, vim is the most popular text editor out there. Even some Windows users tend to use it although being an indigenous Unix utility. But what's the point? There are so many IDEs out there. Why would anyone bother poisoning his life with an endless vim frustration, when he can just install the first Javascript IDE google suggests. Well, although it is probably not suitable for any project, there are some great benefits in sticking with vim at least for a while. The greatest one being the user interface. However, the focus of this article is not that. Many articles can be found on the subject and perhaps I will make one in the future. Today, we will explore the much less highlighted merits of the vim editor.
Continue Reading

Site Footer