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

258 lines
12 KiB
Org Mode
Raw Normal View History

#+TITLE: Go layer
2015-06-10 16:44:30 +00:00
#+TAGS: general|layer|multi-paradigm|programming
2019-05-05 17:26:40 +00:00
2015-06-10 16:44:30 +00:00
[[file:img/go.png]]
2019-05-07 20:05:06 +00:00
* Table of Contents :TOC_5_gh:noexport:
2017-05-22 14:16:12 +00:00
- [[#description][Description]]
- [[#features][Features:]]
- [[#install][Install]]
- [[#layer][Layer]]
- [[#pre-requisites][Pre-requisites]]
2017-05-22 14:16:12 +00:00
- [[#configuration][Configuration]]
- [[#execution][Execution]]
2017-05-22 14:16:12 +00:00
- [[#indentation][Indentation]]
- [[#autoformat][Autoformat]]
- [[#linting][Linting]]
2017-05-22 14:16:12 +00:00
- [[#tests][Tests]]
- [[#coverage][Coverage]]
2017-05-22 14:16:12 +00:00
- [[#guru][Guru]]
- [[#auto-completion][Auto-completion]]
- [[#lsp-backend][LSP backend]]
2017-05-22 14:16:12 +00:00
- [[#working-with-go][Working with Go]]
- [[#go-commands-start-with-m][Go commands (start with =m=):]]
- [[#go-guru][Go Guru]]
2017-05-25 11:19:50 +00:00
- [[#refactoring][Refactoring]]
2015-06-10 16:44:30 +00:00
* Description
This layer adds extensive support for the [[https://golang.org][Go]] programming language.
2015-06-10 16:44:30 +00:00
** Features:
- Run [[https://golang.org/cmd/gofmt/][gofmt]]/[[https://godoc.org/golang.org/x/tools/cmd/goimports][goimports]] on file save (see [[#autoformat][Autoformat]])
- Auto-completion using [[https://github.com/nsf/gocode/tree/master/emacs][go-autocomplete.el]], via the =auto-completion= layer (see [[#auto-completion][Auto-completion]])
- Source analysis using [[https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ][go-guru]] (see [[#guru][Guru]])
2017-05-25 11:19:50 +00:00
- Refactoring with [[http://gorefactor.org/][godoctor]]
- Edit struct field tags with [[https://github.com/fatih/gomodifytags][gomodifytags]]
- Linting with flycheck's built-in checkers or [[https://github.com/golangci/golangci-lint][golangci-lint]] (see [[#linting][Linting]])
- Test generation via [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]] (see [[#tests][Tests]])
- Coverage profile visualization (see [[#coverage][Coverage]])
- List packages faster with [[https://github.com/haya14busa/gopkgs][gopkgs]]
2018-06-09 04:58:50 +00:00
- Fill a structure with default values using the [[https://github.com/davidrjenni/reftools/tree/master/cmd/fillstruct][fillstruct]]
- LSP backend (see [[#lsp-backend][LSP backend]])
2015-06-10 16:44:30 +00:00
* Install
** 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.
2015-06-10 16:44:30 +00:00
** Pre-requisites
You will need =gocode=, =gogetdoc=, =godef=, =godoctor= and many others
to get all the goodies of this layer:
2015-06-10 16:44:30 +00:00
#+BEGIN_SRC sh
GO111MODULE=on go get -v golang.org/x/tools/gopls@latest
go get -u -v golang.org/x/tools/cmd/godoc
go get -u -v golang.org/x/tools/cmd/goimports
go get -u -v golang.org/x/tools/cmd/gorename
go get -u -v golang.org/x/tools/cmd/guru
go get -u -v github.com/cweill/gotests/...
go get -u -v github.com/davidrjenni/reftools/cmd/fillstruct
2017-12-05 14:48:29 +00:00
go get -u -v github.com/fatih/gomodifytags
go get -u -v github.com/godoctor/godoctor
go get -u -v github.com/golangci/golangci-lint/cmd/golangci-lint
go get -u -v github.com/haya14busa/gopkgs/cmd/gopkgs
go get -u -v github.com/josharian/impl
go get -u -v github.com/mdempsky/gocode
go get -u -v github.com/rogpeppe/godef
go get -u -v github.com/zmb3/gogetdoc
2017-12-05 14:48:29 +00:00
#+END_SRC
Make sure that the executables are in your search =$PATH=. Note that they are
installed on =$(go env GOPATH)/bin=, or =$GOBIN= if that environment variable is
defined. For information about setting up =$PATH=, check out the corresponding
section in the FAQ (~SPC h f $PATH RET~).
2015-06-10 16:44:30 +00:00
For best results, make sure that the =auto-completion= and =syntax-checking=
layers are enabled as well.
* Configuration
** Execution
To run the current =main= package with command line arguments, set the value of
=go-run-args= as a file local variable, e.g.
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
// Local Variables:
// go-run-args: "--output run.log"
// End:
2018-09-19 03:54:47 +00:00
#+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.
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
(go :variables go-tab-width 4)
2018-09-19 03:54:47 +00:00
#+END_SRC
If you're using =.editorconfig= in your project, set the value to nil to avoid
conflicts, i.e.
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
(go :variables go-tab-width nil)
2018-09-19 03:54:47 +00:00
#+END_SRC
** Autoformat
To run =gofmt= before save, set the value to a non-nil, i.e.
#+BEGIN_SRC emacs-lisp
(go :variables go-format-before-save t)
#+END_SRC
To use a different formatter, set the value of =gofmt-command=, e.g.
2016-03-30 02:42:45 +00:00
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
(go :variables gofmt-command "goimports")
2018-09-19 03:54:47 +00:00
#+END_SRC
2016-03-30 02:42:45 +00:00
** Linting
If you wish to use =golangci-lint=, set the following layer variable to non-nil:
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
(go :variables go-use-golangci-lint t)
2018-09-19 03:54:47 +00:00
#+END_SRC
Check [[https://github.com/golangci/golangci-lint][golangci-lint]] and [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] for more details.
** Tests
If you're using =gocheck= or =testify= in your project you can use the
=go-use-gocheck-for-testing= or =go-use-testify-for-testing= variable to enable
suite testing and to get single function testing to work.
2015-06-10 16:44:30 +00:00
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=.
2018-07-10 10:57:25 +00:00
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
(go :variables go-use-test-args "-race -timeout 10s")
2018-09-19 03:54:47 +00:00
#+END_SRC
** Coverage
=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=.
2016-10-03 04:20:52 +00:00
** Guru
If you would like to use the =Go Guru= bindings in your work, 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 Gos recursive operator is supported. In addition, you can
prefix it with =-= to exclude a package from searching.
2016-10-03 04:20:52 +00:00
** Auto-completion
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 built-in objects or
being fully dependent on installed binary files to provide its suggestions.
2018-02-14 22:18:09 +00:00
A more modern and complete solution is provided by =gogetdoc=, which is able to
precisely detect all documentations in your go projects independently from where
they have been added. This is also the recommended choice from =go-mode.el=.
2018-02-14 22:18:09 +00:00
To choose =gocode= nothing more needs to be done. To use =gogetdoc= you need to set
the layer variable:
2018-02-14 22:18:09 +00:00
2018-09-19 03:54:47 +00:00
#+BEGIN_SRC emacs-lisp
2018-02-14 22:18:09 +00:00
(go :variables godoc-at-point-function 'godoc-gogetdoc)
2018-09-19 03:54:47 +00:00
#+END_SRC
2018-02-14 22:18:09 +00:00
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.
2018-09-19 03:54:47 +00:00
- Run =gocode set autobuild true= to have gocode attempt to run =go install ./...=
for you.
- You can configure your task runner to run the =go install ./...= command on every
file change.
** LSP backend
To enable the LSP backend, ensure that the =lsp= layer is enabled, and set the
layer variable =go-backend=:
#+BEGIN_SRC elisp
(go :variables go-backend 'lsp)
#+END_SRC
You can check [[https://www.github.com/emacs-lsp/lsp-mode/][lsp-mode]] for the gory details.
The 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 is 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~.
* Working with Go
2015-06-10 16:44:30 +00:00
** 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 |
2015-06-10 16:44:30 +00:00
** Go Guru
| Key binding | Description |
|-------------+------------------------------------------------------|
2017-12-18 03:12:44 +00:00
| ~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 |
2017-12-18 03:12:44 +00:00
| ~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 |
2017-12-18 03:12:44 +00:00
| ~SPC m f o~ | go-guru set analysis scope |
| ~SPC m f p~ | go-guru show what the select expression points to |
2017-12-18 03:12:44 +00:00
| ~SPC m f r~ | go-guru show referrers |
| ~SPC m f s~ | go-guru show callstack |
2017-05-25 11:19:50 +00:00
** 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 (with =gomodifytags=) |
| ~SPC m r F~ | Remove field tags (with =gomodifytags=) |
| ~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 (with =go-fillstruct=) |
| ~SPC m r t~ | Toggle declaration and assignment |