#+TITLE: GO layer

[[file:img/go.png]]

* Table of Contents                                         :TOC_4_gh:noexport:
 - [[#description][Description]]
   - [[#features][Features:]]
 - [[#install][Install]]
   - [[#pre-requisites][Pre-requisites]]
   - [[#layer][Layer]]
 - [[#configuration][Configuration]]
   - [[#formatting][Formatting]]
   - [[#indentation][Indentation]]
   - [[#tests][Tests]]
 - [[#working-with-go][Working with Go]]
   - [[#go-commands-start-with-m][Go commands (start with =m=):]]
   - [[#go-oracle][Go Oracle]]

* Description
This layer adds extensive support for go.

** Features:
- gofmt/goimports on file save
- Auto-completion using [[https://github.com/nsf/gocode/tree/master/emacs][go-autocomplete]] (with the =auto-completion= layer)
- Source analysis using [[http://golang.org/s/oracle-user-manual][go-oracle]]
- Linting with flycheck's built-in checkers or flycheck-gometalinter

* Install
** Pre-requisites
You will need =gocode= and =godef=:

#+BEGIN_SRC sh
  go get -u -v github.com/nsf/gocode
  go get -u -v github.com/rogpeppe/godef
  go get -u -v golang.org/x/tools/cmd/oracle
  go get -u -v golang.org/x/tools/cmd/gorename
  go get -u -v golang.org/x/tools/cmd/goimports
#+END_SRC

If you wish to use =gometalinter= set the value of =go-use-gometalinter=:

#+begin_src emacs-lisp
  (go :variables go-use-gometalinter t)
#+end_src

and install the tool:

#+BEGIN_SRC sh
  go get -u -v github.com/alecthomas/gometalinter
  gometalinter --install --update
#+END_SRC

For more information read [[https://github.com/alecthomas/gometalinter/blob/master/README.md][gometalinter README.md]]
and [[https://github.com/favadi/flycheck-gometalinter/blob/master/README.md][flycheck-gometalinter README.md]]

Make sure that =gocode= executable is in your PATH. For information about
setting up =$PATH=, check out the corresponding section in the FAQ (~SPC h SPC
$PATH RET~).

For best results, make sure that the =auto-completion= and =syntax-checking=
layers are enabled as well.

** Layer
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
add =go= to the existing =dotspacemacs-configuration-layers= list in this
file.

* Configuration
** Formatting
By default, go buffers are run through =gofmt= on save. To use a different
formatter, set the value of =gofmt-command=, e.g.

#+begin_src emacs-lisp
  (setq gofmt-command "goimports")
#+end_src

or

#+begin_src emacs-lisp
  (go :variables gofmt-command "goimports")
#+end_src

** Indentation
By default, the tab width in Go mode is 8 spaces. To use a different value set
the layer variable =go-tab-width=, e.g.

#+begin_src emacs-lisp
  (go :variables go-tab-width 4)
#+end_src

** Tests
If you're using =gocheck= in your project you can use the
=go-use-gocheck-for-testing= variable to enable suite testing and to get single
function testing to work.

* Working with Go
** Go commands (start with =m=):

| Key Binding | Description                                                                           |
|-------------+---------------------------------------------------------------------------------------|
| ~SPC m h h~ | godoc at point                                                                        |
| ~SPC m i g~ | goto imports                                                                          |
| ~SPC m i a~ | add import                                                                            |
| ~SPC m i r~ | remove unused import                                                                  |
| ~SPC m e b~ | go-play buffer                                                                        |
| ~SPC m e r~ | go-play region                                                                        |
| ~SPC m e d~ | download go-play snippet                                                              |
| ~SPC m x x~ | run "go run" for the current 'main' package                                           |
| ~SPC m g a~ | jump to matching test file or back from test to code file                             |
| ~SPC m g g~ | go jump to definition                                                                 |
| ~SPC m r n~ | go rename                                                                             |
| ~SPC m t p~ | run "go test" for the current package                                                 |
| ~SPC m t P~ | run "go test" for the current package and all packages under it                       |
| ~SPC m t t~ | run "go test" for the function you're currently in (while you're in a _.test.go file) |
| ~SPC m t s~ | run "go test" for the suite you're currently in (requires gocheck)                    |

** Go Oracle

| Key Binding | Description                                                |
|-------------+------------------------------------------------------------|
| ~SPC m r o~ | go-oracle set analysis scope                               |
| ~SPC m r <~ | go-oracle show possible callers                            |
| ~SPC m r >~ | go-oracle show call targets                                |
| ~SPC m r c~ | go-oracle show channel sends/receives                      |
| ~SPC m r d~ | go-oracle show definition                                  |
| ~SPC m r f~ | go-oracle show free variables                              |
| ~SPC m r g~ | go-oracle show callgraph                                   |
| ~SPC m r i~ | go-oracle show implements relation                         |
| ~SPC m r p~ | go-oracle show what the select expression points to        |
| ~SPC m r r~ | go-oracle show all references to object                    |
| ~SPC m r s~ | go-oracle show callstack                                   |
| ~SPC m r t~ | go-oracle describe selected syntax, kind, type and methods |
