Writing Go in Vim

Bernerd Schaefer

I recently needed to update my Vim setup for writing Go (the latest release no longer ships with its own Vim plugin), so I thought I’d take this chance to document and share how to work productively on Go with Vim.

Prerequisites

You’ll need a working Go installation to make use of the Vim setup we’ll look at. I’d recommend either following Go’s official installation instructions, or, if you’re using Homebrew, run brew install go.

Then you’ll need to choose the location of your default Go workspace. If you’ve never done this before, How To Write Go Code will walk you through the steps to set up your work environment.

vim-go

vim-go seems to be the most popular Vim plugin for working with go, so that’s what we’ll use. Follow the installation instructions (or fetch and add to your runtimepath). Open a new Vim instance and run :GoInstallBinaries to get the necessary go tools we’ll need.

Once the plugin is installed, these are some of the features it gives you when writing Go:

Formatting (on save)

The default configuration for vim-go is to run :GoFmt when a file is saved. That means if you save this file:

package main

func main() {
fmt.Println("Hello, world!")
}

It will be automatically rewritten to the correct form:

package main

func main() {
  fmt.Println("Hello, world!")
}

If you change the command used by :GoFmt to goimports, it will also manage your imports (e.g., by inserting the missing “fmt” import in the above example):

" format with goimports instead of gofmt
let g:go_fmt_command = "goimports"

Automatically formatting and importing packages on save is a popular choice; but if you feel it is slowing down Vim or confusing you, you can disable it:

" disable fmt on save
let g:go_fmt_autosave = 0

You can still use :GoFmt to manually fix up your code.

Import management

If you’re not using goimports as your formatter (and, sometimes, even if you are), you’ll need to manage your imports list. vim-go provides a few useful commands for this:

  • :GoImport [path]: adds "path" to the correct place in the list of imports.
  • :GoImportAs [name] [path]: adds name "path" to the correct place in the list of imports.
  • :GoDrop [path]: drops package from the list of imports.
  • :GoImports: runs goimports on the file.

Documentation

Go’s browser-based documentation tools are great, but it’s often useful to have quick access to the docs you need from within Vim. For that, there’s :GoDoc. It displays Go documentation in a split pane, and can be called a few ways:

  • :GoDoc: with no arguments, this will look up the identifier under the cursor; note that it is only able to look up top-level identifiers like fmt.Println, os.O_RDONLY, and bytes.Buffer.
  • :GoDoc package: brings up the documentation for a package; for example :GoDoc fmt.
  • :GoDoc package name: brings up the function/type/identifier documentation; for example :GoDoc json/encoding NewEncoder or :GoDoc os FileInfo.

And more

vim-go provides a number of other commands (like :GoBuild and :GoTest), as well as configuration options, so be sure to read through :help vim-go to learn more!