Seven Story Rabbit Hole

Sometimes awesome things happen in deep rabbit holes. Or not.

   images

Configure Emacs as a Go Editor From Scratch

This explains the steps to get a productive Emacs environment for Go programming on OSX, starting from scratch.

Install Emacs

I recommend using the emacs from emacsformacosx.com.

It has a GUI installer so I won’t say much more about it.

Install lastest version of Go

See Installing Go

After installing, you’ll want to define the following environment variables in your ~/.bash_profile.

1
2
3
4
export GOROOT=/usr/local/go            
export GOPATH=~/Development/gocode
export PATH=$PATH:$GOROOT/bin
export PATH=$PATH:$GOPATH/bin

These might be different on your system.

Install additional go tools (godoc, etc)

To get the godoc tool as well as others, run:

1
go get golang.org/x/tools/cmd/...

Install Melpa

Melpa is a package manager for Emacs, and is required for go-mode

To configure emacs for melpa:

  • Create a new file ~/.emacs.d/init.el
  • Add the following contents:
1
2
3
(require 'package)
(add-to-list 'package-archives
  '("melpa" . "http://melpa.milkbox.net/packages/") t)

Restart emacs and run M-x package-list-packages and you should see it contacting http://melpa.milkbox.net and you should also see lot of packages listed as being from the melpa archive.

Install go-mode

Run M-x package-install and when prompted, enter go-mode and hit enter.

Restart Emacs and open a .go file, you should see the mode as “Go” rather than “Fundamental”.

For a full description of what go-mode can do for you, see Dominik Honnef’s blog, but one really useful thing to be aware of is that you can quickly import packages via C-c C-a

Update Emacs path to find godoc

Run M-x package-install and enter exec-path-from-shell

I got this warning:

1
2
3
4
5
6
7
8
Compiling file /Users/tleyden/.emacs.d/elpa/exec-path-from-shell-20160112.2246/exec-path-from-shell-pkg.el at Sat Feb  6 18:20:55 2016
Entering directory `/Users/tleyden/.emacs.d/elpa/exec-path-from-shell-20160112.2246/'

Compiling file /Users/tleyden/.emacs.d/elpa/exec-path-from-shell-20160112.2246/exec-path-from-shell.el at Sat Feb  6 18:20:55 2016

In exec-path-from-shell-setenv:
exec-path-from-shell.el:189:11:Warning: assignment to free variable
    `eshell-path-env'

Restart emacs.

Update Emacs config for godoc

It’s really useful to be able to able to pull up 3rd party or standard library docs from within Emacs using the godoc tool.

PATH

Add the following to your ~/.emacs.d/init.el file so that it gets the PATH environment:

1
2
3
4
5
6
7
8
9
10
(defun set-exec-path-from-shell-PATH ()
  (let ((path-from-shell (replace-regexp-in-string
                          "[ \t\n]*$"
                          ""
                          (shell-command-to-string "$SHELL --login -i -c 'echo $PATH'"))))
    (setenv "PATH" path-from-shell)
    (setq eshell-path-env path-from-shell) ; for eshell users
    (setq exec-path (split-string path-from-shell path-separator))))

(when window-system (set-exec-path-from-shell-PATH))

GOPATH

1
(setenv "GOPATH" "/Users/tleyden/Development/gocode")

(replace the above path to the absolute path to the directory where you store your Go code)

After doing this step, you should be able to run M-x godoc and it should be able to autocomplete paths of packages. (of course, you may want to go get some packages first if you don’t have any)

Automatically call gofmt on save

gofmt reformats code into the One True Go Style Coding Standard. You’ll want to call it every time you save a file.

Add these to your ~/.emacs.d/init.el:

1
2
(add-to-list 'exec-path "/Users/tleyden/Development/gocode/bin")
(add-hook 'before-save-hook 'gofmt-before-save)

After this step, whenever you save a Go file, it will automatically reformat the file with gofmt.

Godef

Godef is essential: it lets you quickly jump around the code, as you might be used to with a full featured IDE.

Install godef itself:

1
go get github.com/rogpeppe/godef

Installing go-mode automatically installs godef bindings.

To verify that godef bindings work:

  • Putting the cursor over a method name
  • Try doing M-x godef-jump to jump into the method, and M-* to go back.

In order to add godef key bindings, add these to your ~/.emacs.d/init.el:

1
2
3
4
5
6
(defun my-go-mode-hook ()
  ; Call Gofmt before saving                                                    
  (add-hook 'before-save-hook 'gofmt-before-save)
  ; Godef jump key binding                                                      
  (local-set-key (kbd "M-.") 'godef-jump))
(add-hook 'go-mode-hook 'my-go-mode-hook)

and remove your previous call to (add-hook 'before-save-hook 'gofmt-before-save) since it’s now redundant

Now you can jump into code with M-. and jump back with M-*

Autocomplete

Install melpa auto-complete via M-x package-install followed by auto-complete

Add the following to your ~/.emacs.d/init.el file:

1
2
3
(defun auto-complete-for-go ()
  (auto-complete-mode 1))
(add-hook 'go-mode-hook 'auto-complete-for-go)

Restart emacs, and if you open a .go file the mode should be Go AC (AC == AutoComplete)

Before further verifying, we need to install go-autocomplete in the next step.

go-autocomplete

The basic autocomplete installed is not as “go aware” as it should be. The go-autocomplete (aka nsf/gocode) package fixes that.

Install the gocode binary

1
go get -u github.com/nsf/gocode

and then install the melpa package via M-x package-install followed by go-autocomplete

After installing go-autocomplete, open your ~/.emacs.d/init.el file and make sure the following was added:

1
2
3
(defun auto-complete-for-go ()
(auto-complete-mode 1))
 (add-hook 'go-mode-hook 'auto-complete-for-go)

If it was not added, you’ll need to add it yourself.

You’ll also need the following (as recommended in gocode issue 325):

1
2
(with-eval-after-load 'go-mode
   (require 'go-autocomplete))

Now restart emacs, and when you start typing the name of a field in a struct it will popup something that looks like this:

screenshot

Note that is more “go-aware” than the default auto-complete functionality.

Customize the emacs compile command to run go build

It’s convenient to be able to run M-x compile to compile and test your Go code from within emacs.

To do that, edit your ~/.emacs.d/init.el and replace your go-mode hook with:

1
2
3
4
5
6
7
8
9
10
(defun my-go-mode-hook ()
  ; Call Gofmt before saving
  (add-hook 'before-save-hook 'gofmt-before-save)
  ; Customize compile command to run go build
  (if (not (string-match "go" compile-command))
      (set (make-local-variable 'compile-command)
           "go build -v && go test -v && go vet"))
  ; Godef jump key binding
  (local-set-key (kbd "M-.") 'godef-jump))
(add-hook 'go-mode-hook 'my-go-mode-hook)

After that, restart emacs, and when you type M-x compile, it should try to execute go build -v && go test -v && go vet instead of the default behavior. On some projects, you might also want to run go generate before go build

Power tip: you can jump straight to each compile error by running C-x `. Each time you do it, it will jump to the next error.

Continue to Part 2

go-imports and go-oracle are covered in Part 2

References

Comments