286 lines
12 KiB
Org Mode
286 lines
12 KiB
Org Mode
#+TITLE: GO layer
|
||
|
||
[[file:img/go.png]]
|
||
|
||
* Table of Contents :TOC_4_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 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:
|
||
|
||
#+BEGIN_SRC sh
|
||
go get -u github.com/sourcegraph/go-langserver
|
||
#+END_SRC
|
||
|
||
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
|
||
|
||
** 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 subs 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 |
|