This is a squash commit, it includes: * Add go run and go test command variables * Update go README for go-run-command and go-test-command * Update CHANGELOG
14 KiB
Go layer
Description
This layer adds extensive support for the Go programming language.
Features:
- Run gofmt / goimports on file save (see Autoformat)
- Auto-completion using go-autocomplete.el, via the
auto-completion
layer (see Auto-completion) - Source analysis using go-guru (see Guru)
- Refactoring with godoctor
- Edit struct field tags with gomodifytags
- Linting with flycheck's built-in checkers or golangci-lint (see Linting)
- Test generation via go-gen-test (see Tests)
- Coverage profile visualization (see Coverage)
- List packages faster with gopkgs
- Fill a structure with default values using the fillstruct
- LSP backend (see LSP backend)
- Interactive debugger using dap-mode
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.
Choosing a backend
To choose a default backend set the layer variable go-backend
:
(go :variables go-backend 'go-mode)
Alternatively the lsp
backend will be automatically chosen if the layer lsp
is used and you did not specify any value for go-backend
.
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
lsp
backend:
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((go-mode (go-backend . lsp)))
Note: you can easily add a directory local variable with SPC f v d
.
Pre-requisites
You will need gocode
, gogetdoc
, godef
, godoctor
and many others
to get all the goodies of this layer:
GO111MODULE=on go get -v golang.org/x/tools/gopls@latest
GO111MODULE=on CGO_ENABLED=0 go get -v -trimpath -ldflags '-s -w' github.com/golangci/golangci-lint/cmd/golangci-lint
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
go get -u -v github.com/fatih/gomodifytags
go get -u -v github.com/godoctor/godoctor
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
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
).
For best results, make sure that the auto-completion
and syntax-checking
layers are enabled as well.
Configuration
Execution
By default, the go run command is go run
. If you want to use a different
command or run with environment variables, set the layer variable
go-run-command
.
(go :variables go-run-command "ENV_VAR=foo go run")
To run the current main
package with command line arguments, set the value of
go-run-args
as a file local variable, e.g.
// Local Variables:
// go-run-args: "--output run.log"
// End:
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.
(go :variables go-tab-width 4)
If you're using .editorconfig
in your project, set the value to nil to avoid
conflicts, i.e.
(go :variables go-tab-width nil)
Autoformat
To run gofmt
before save, set the value to a non-nil, i.e.
(go :variables go-format-before-save t)
To use a different formatter, set the value of gofmt-command
, e.g.
(go :variables gofmt-command "goimports")
Linting
If you wish to use golangci-lint
, set the following layer variable to non-nil:
(go :variables go-use-golangci-lint t)
Check golangci-lint and flycheck-golangci-lint for more details.
Please remember that without properly configured flycheck-golangci-lint
variables golangci-lint
may not run as expected. The recommended way is to use a .golangi.yml
in your project.
But if this is not possible you can also set global command line flags for golangci-lint
.
Especially important is the selection of which linters to run and whether to lint test files too.
It may happen from time to time that golangci-lint
is not able to parse a buffers content
properly. This normally happens when there are basic errors in the file which prevent more
complex analytics to run. In this case a set of errors will be shown at the top of the
current buffer which are not properly parsed by flycheck. Spacemacs still shows basic
errors in your buffer. When these have been fixed golangci-lint
will regenerate
and further diagnostic data will be made available.
When this happens please report a bug to `golangci-lint` they are working hard to fix these.
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.
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.
By default, the go test command is go test
. If you want to use a different
command or test with environment variables, set the layer variable
go-test-command
.
(go :variables go-test-command "ENV_VAR=foo go test")
To provide additional arguments to go test
, specify go-use-test-args
.
(go :variables go-use-test-args "-race -timeout 10s")
Coverage
go-coverage-display-buffer-func
controls how go-coverage
should display
the coverage buffer. See display-buffer for a list of possible functions.
The default value is display-buffer-reuse-window
.
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 Go's recursive operator is supported. In addition, you can
prefix it with -
to exclude a package from searching.
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.
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
.
To choose gocode
nothing more needs to be done. To use gogetdoc
you need to set
the layer variable:
(go :variables godoc-at-point-function 'godoc-gogetdoc)
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 rungo 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
:
(go :variables go-backend 'lsp)
You can check 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:
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((go-mode (go-backend . go-mode)))
Note: you can easily add a directory local variable with SPC f v d
.
Debugger
Using the dap
layer you'll get access to all the DAP key bindings, see the complete list of key bindings on the dap layer description.
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 (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 |