Go development using GNU Emacs
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))