spacemacs/layers/+lang/go/README.org

296 lines
12 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: GO layer
#+TAGS: general|layer|multi-paradigm|programming
[[file:img/go.png]]
* Table of Contents :TOC_5_gh:noexport:
- [[#description][Description]]
- [[#features][Features:]]
- [[#install][Install]]
- [[#pre-requisites][Pre-requisites]]
- [[#lsp-backend][LSP backend]]
- [[#layer][Layer]]
- [[#configuration][Configuration]]
- [[#indentation][Indentation]]
- [[#tests][Tests]]
- [[#guru][Guru]]
- [[#autocomplete][Autocomplete]]
- [[#working-with-go][Working with Go]]
- [[#go-commands-start-with-m][Go commands (start with =m=):]]
- [[#go-guru][Go Guru]]
- [[#refactoring][Refactoring]]
* Description
This layer adds extensive support for go to Spacemacs.
** Features:
- gofmt/goimports on file save (to enable, see [[#configuration][Configuration]])
- Auto-completion using [[https://github.com/nsf/gocode/tree/master/emacs][go-autocomplete]] (with the =auto-completion= layer)
- Source analysis using [[https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ][go-guru]]
- Refactoring with [[http://gorefactor.org/][godoctor]]
- Edit struct field tag with [[https://github.com/fatih/gomodifytags][gomodifytags]]
- Linting with flycheck's built-in checkers or flycheck-gometalinter
- Coverage profile visualization
- Test generation with [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]]
- Get packages faster with [[https://github.com/haya14busa/gopkgs][gopkgs]]
- Fill a structure with default values using the [[https://github.com/davidrjenni/reftools/tree/master/cmd/fillstruct][fillstruct]]
- LSP backend
* Install
** Pre-requisites
You will need =gocode=, =gogetdoc=, =godef=, =godoctor= and many others
to get all the goodies of this layer:
#+BEGIN_SRC sh
go get -u -v github.com/mdempsky/gocode
go get -u -v github.com/rogpeppe/godef
go get -u -v golang.org/x/tools/cmd/guru
go get -u -v golang.org/x/tools/cmd/gorename
go get -u -v golang.org/x/tools/cmd/goimports
go get -u -v golang.org/x/tools/cmd/godoc
go get -u -v github.com/zmb3/gogetdoc
go get -u -v github.com/cweill/gotests/...
go get -u github.com/haya14busa/gopkgs/cmd/gopkgs
go get -u -v github.com/davidrjenni/reftools/cmd/fillstruct
go get -u github.com/josharian/impl
#+END_SRC
If you wish to use a linters aggregator tool, you can enable =gometalinter= or =golangci-lint=.
If you wish to use =gometalinter= set the value of =go-use-gometalinter= to t:
#+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]]
If you wish to use =golangci-lint= set the value of =go-use-golangci-lint= to t:
#+BEGIN_SRC emacs-lisp
(go :variables go-use-golangci-lint t)
#+END_SRC
and install the tool:
#+BEGIN_SRC sh
go get -u github.com/golangci/golangci-lint/cmd/golangci-lint
#+END_SRC
For more information read [[https://github.com/golangci/golangci-lint][golangci-lint README.md]]
and [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint README.md]]
If you wish to use =godoctor= for refactoring, install it too:
#+BEGIN_SRC sh
go get -u -v github.com/godoctor/godoctor
go install github.com/godoctor/godoctor
#+END_SRC
If you want to use =gomodifytags= to edit field tags, install it too:
#+BEGIN_SRC sh
go get -u -v github.com/fatih/gomodifytags
#+END_SRC
Make sure that the =gocode= executable is in your PATH. For information about
setting up =$PATH=, check out the corresponding section in the FAQ (~SPC h f
$PATH RET~).
For best results, make sure that the =auto-completion= and =syntax-checking=
layers are enabled as well.
** LSP backend
To enable the LSP backend set the layer variable =go-backend=:
#+BEGIN_SRC elisp
(go :variables go-backend 'lsp)
#+END_SRC
You also need to install the Go Language Server.
Consult the installation command for the desired language server found at [[https://www.github.com/emacs-lsp/lsp-mode/][lsp-mode]] for instructions.
Backend can be chosen on a per project basis using directory local variables
(files named =.dir-locals.el= at the root of a project), an example to use the
=go-mode= backend:
#+BEGIN_SRC elisp
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((go-mode (go-backend . go-mode)))
#+END_SRC
*Note:* you can easily add a directory local variable with ~SPC f v d~.
** 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
To run =gofmt= before save, set the value to a non-nil, e.g.
#+BEGIN_SRC emacs-lisp
(setq go-format-before-save t)
#+END_SRC
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
To run current main package with command line arguments, set the value of
=go-run-args= as file local variable, e.g.
#+BEGIN_SRC emacs-lisp
// Local Variables:
// go-run-args: "--output run.log"
// End:
#+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
If you're using =.editorconfig= in your project, set the value to nil to avoid
confliction, e.g.
#+BEGIN_SRC emacs-lisp
(go :variables go-tab-width nil)
#+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.
=go-coverage-display-buffer-func= controls how =go-coverage= should display
the coverage buffer. See [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Choosing-Window.html][=display-buffer=]] for a list of possible functions.
The default value is =display-buffer-reuse-window=.
Tests are run in a compilation buffer displayed in a popup window that can be
closed by pressing ~C-g~ from any other window. The variable
=go-test-buffer-name= can be customized to set the output buffer name.
To provide additional arguments to go test, specify =go-use-test-args=.
#+BEGIN_SRC emacs-lisp
(go :variables go-use-test-args "-race -timeout 10s"
#+END_SRC
** Guru
Go Oracle has been deprecated as of October 1, 2016, it's replacement is =go-guru=.
If you would like to use the =goguru= bindings in your work, you will need to
install it, and in your project you will need to set the scope with ~SPC m f o~.
The scope is a comma separated set of packages, and =go=s recursive operator is
supported. In addition, you can prefix with =-= to exclude a package from
searching.
In addition, =GOPATH= must be set prior to =go-guru= initialization.
** Autocomplete
For auto-completion there are actually two choices. First there is the classic =gocode=.
This has been around for quite a long time now, however =gocode= has many shortcomings like
not being able to show documentation for build-in objects or being fully dependent on installed binary
files to provide its suggestions.
A more modern and complete solution is provided by =gogetdoc= which is able to
precisely detect all documentations in your go projects independent on where
they have been added. This is also the choice recommended from =go-mode.el=.
To choose =gocode= nothing more needs to be done. To use =gogetdoc= you need to set
#+BEGIN_SRC emacs-lisp
(go :variables godoc-at-point-function 'godoc-gogetdoc)
#+END_SRC
in your =dotfile=.
If you choose to use =gocode= there are some suggestions to improve its results.
As =gocode= uses the output from installed binary files to provide its suggestions.
You have a few options to ensure you always get up to date suggestions:
- Run =go install ./...= in your package directory when you make a file change.
- Run =gocode set autobuild true= to have gocode attempt to run =go install ./...=
for you.
- You can configure your task runner to run =go install ./...= command on every
file change.
* Working with Go
** Go commands (start with =m=):
| Key binding | Description |
|---------------+---------------------------------------------------------------------------------------|
| ~SPC m =~ | run "go fmt" |
| ~SPC m e b~ | go-play buffer |
| ~SPC m e d~ | download go-play snippet |
| ~SPC m e r~ | go-play region |
| ~SPC m g a~ | jump to matching test file or back from test to code file |
| ~SPC m g c~ | open a clone of the current buffer with a coverage info (=go tool cover -h= for help) |
| ~SPC m g g~ | go jump to definition |
| ~SPC m h h~ | godoc at point |
| ~SPC m i a~ | add import |
| ~SPC m i g~ | goto imports |
| ~SPC m i r~ | remove unused import |
| ~SPC m r n~ | go rename |
| ~SPC m t P~ | run "go test" for the current package and all packages under it |
| ~SPC m t g f~ | generate tests for all exported functions |
| ~SPC m t g F~ | generate tests for all functions |
| ~SPC m t g g~ | DWIM generate test for the function in the active region |
| ~SPC m t p~ | run "go test" for the current package |
| ~SPC m t s~ | run "go test" for the suite you're currently in (requires gocheck) |
| ~SPC m t t~ | run "go test" for the function you're currently in (while you're in a _.test.go file) |
| ~SPC m x x~ | run "go run" for the current 'main' package |
** Go Guru
| Key binding | Description |
|-------------+------------------------------------------------------|
| ~SPC m f <~ | go-guru show possible callers |
| ~SPC m f >~ | go-guru show call targets |
| ~SPC m f c~ | go-guru show channel sends/receives |
| ~SPC m f d~ | go-guru describe symbol at point |
| ~SPC m f e~ | go-guru show possible contants/types for error value |
| ~SPC m f f~ | go-guru show free variables |
| ~SPC m f i~ | go-guru show implements relation |
| ~SPC m f j~ | go-guru jump to symbol definition |
| ~SPC m f o~ | go-guru set analysis scope |
| ~SPC m f p~ | go-guru show what the select expression points to |
| ~SPC m f r~ | go-guru show referrers |
| ~SPC m f s~ | go-guru show callstack |
** Refactoring
| Key binding | Description |
|-------------+-----------------------------------------------------------------|
| ~SPC m r d~ | Add comment stubs |
| ~SPC m r e~ | Extract code as new function |
| ~SPC m r f~ | Add field tags |
| ~SPC m r F~ | Remove field tags |
| ~SPC m r i~ | Generate method stubs for implementing an interface (=go-impl=) |
| ~SPC m r n~ | Rename (with =godoctor=) |
| ~SPC m r N~ | Rename (with =go-rename=) |
| ~SPC m r s~ | Fill structure with default values |
| ~SPC m r t~ | Toggle declaration and assignment |