584392bd92
There was a edge case with the declaration of the `lsp` layer in `layers.el` files. The `hy` layer depends on the `python` layer which in turn depends on the `lsp` layer if and only if the `python-backend` layer variable is set to `lsp`. When the `hy` layer was declared first then it declares the `python` layer without its layer variables, thus the `lsp` layer was not declared because the `python-backend` variable was not set. The fix is to gather all the layer dependencies and resolve them only after all the used layers have been declared. * new function `configuration-layer/declare-layer-dependencies` * replace all calls to `configuration-layer/declare-layer` by the new function except for distribution layers (we declare layer dependencies right away in distribution layers) |
||
---|---|---|
.. | ||
img | ||
config.el | ||
funcs.el | ||
layers.el | ||
packages.el | ||
README.org |
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)
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
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/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
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
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.
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.
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
.
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 |