In this post I'll describe how I use GNU Emacs in Go development. I past year and a half I changed my configuration several times and I'm sure that more changes are coming as tools get better. I'm not going into details about any of Emacs packages used in this article. Please check their documentation for available commands. I'll try to keep this article up to date as time goes by.

go-mode

First, we need syntax highlighting, formatting and other functionality provided by mayor programming modes in Emacs. In the case of Go programming language, that is go-mode. go-mode adds even more functionality, but I'll not cover those in this article. It's available on Melpa.

go-projectile

I use projectile for project management in GNU Emacs and go-projectile was natural choice for me. You can install it using Melpa.

go-projectile can manage $GOPATH for you. Before using go-projectile I was setting $GOPATH using .dir-locals.el per project, similar as described in my other article about node_modules/.bin. Unfortunately, this doesn't work all the times, only after projectile changes project using projectile-switch-project. We can fix that.

Second thing that go-projectile does is installing different Go development tools needed for other GNU Emacs packages into one single location. For example for code completion we need gocode, for code analysis we need oracle, etc. In order to install those packages just run M-x go-projectile-install-tools. There is also go-projectile-update-tools when you need to update installed tools. All tools will be installed in your ~/.emacs.d/gotools. You can change that directory by changing go-projectile-tools-path in your Emacs configuration. You can see all installed tools in the source of go-projectile.

Unfortunately, go-projectile doesn't change your $PATH and those tools are not available outside go-projectile. We can change that too.

Whole setup part looks like this:

(require 'go-projectile)

(eval-after-load 'go-mode
  '(progn
    ;; Set $GOPATH
    (go-projectile-set-gopath)
    ;; Set $PATH to $PATH:~/.emacs.d/gotools/bin
    (go-projectile-tools-add-path)))

Error checking

I use flycheck and it comes with build-in support for go vet, golint, go fmt, go build and errcheck. Three of those tools come together with go, other two you get after installing go tools with go-projectile. Flycheck will run all of those one after another. That may be too much and in that case you can disable specific checker using flycheck-disable-checker.

Code completion

I use company-mode for code completion in GNU Emacs. The is extension for company-mode for Go programming language called company-go.

(add-hook 'go-mode-hook (lambda ()
  (set (make-local-variable 'company-backends) '(company-go))
  (company-mode)))

Snippets

If you are using yas-snippet package, there is also yasnippet-go (manual install) or go-snippets (also on Melpa).

ELDoc

When installing go-projectile using Melpa, you will also get go-eldoc package that provides go documentation. We can initialize like this:

(add-hook 'go-mode-hook 'go-eldoc-setup)

oracle.el

One of the installed tools is oracle analysis tool and includes oracle.el that integrate oracle into GNU Emacs. We can load it (if oracle is installed):

(defvar oracle-file (concat go-projectile-tools-path "/src/"
                            (cdr (assq 'oracle go-projectile-tools))
                            "/oracle.el"))
(if (file-exists-p oracle-file)
		(load-file oracle-file))
Share on: