#+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 |