[goimport->goimports] Enduring the frustration of a longstanding typo, I've finally resolved to correct it. The change updates "goimport" to "goimport," including all related documentation and tests.

Additionally, I've set gopls as the default tool for both gofmt and goimports. This integration will be quicker than executing a separate command in the background and analyzing its output.
pull/429/merge
ray-x 2 months ago
parent 9ac3e6faa3
commit fe8196f9d1

@ -1,7 +1,8 @@
# go.nvim # go.nvim
A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. It is written in Lua and async as much as possible. A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. It is written in Lua and async as much as
PR & Suggestions are welcome. possible. PR & Suggestions are welcome.
<p align="center" width="100%"> <p align="center" width="100%">
<img width="38%" <img width="38%"
src="https://user-images.githubusercontent.com/1681295/276892590-8ca24048-5c05-497f-9789-c5732a7b232b.png"> src="https://user-images.githubusercontent.com/1681295/276892590-8ca24048-5c05-497f-9789-c5732a7b232b.png">
@ -10,28 +11,31 @@ The plugin covers most features required for a gopher.
- Perproject setup. Allows you setup plugin behavior per project based on project files(launch.json, .gonvim) - Perproject setup. Allows you setup plugin behavior per project based on project files(launch.json, .gonvim)
- Async jobs with libuv - Async jobs with libuv
- Syntax highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support treesitter, try - Syntax highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support
[aurora](https://github.com/ray-x/aurora), [starry.nvim](https://github.com/ray-x/starry.nvim). Also, there are quite a few listed in [awesome-neovim](https://github.com/rockerBOO/awesome-neovim) treesitter, try [aurora](https://github.com/ray-x/aurora), [starry.nvim](https://github.com/ray-x/starry.nvim). Also,
- All the GoToXxx (E.g reference, implementation, definition, goto doc, peek code/doc etc) You need lspconfig setup. There are lots of posts on how to there are quite a few listed in [awesome-neovim](https://github.com/rockerBOO/awesome-neovim)
set it up. You can also check my [navigator](https://github.com/ray-x/navigator.lua) gopls setup [lspconfig.lua](https://github.com/ray-x/navigator.lua/blob/master/lua/navigator/lspclient/clients.lua) - All the GoToXxx (E.g reference, implementation, definition, goto doc, peek code/doc etc) You need lspconfig setup.
There are lots of posts on how to set it up. You can also check my [navigator](https://github.com/ray-x/navigator.lua)
gopls setup [lspconfig.lua](https://github.com/ray-x/navigator.lua/blob/master/lua/navigator/lspclient/clients.lua)
- gopls commands: e.g. fillstruct, organize imports, list modules, list packages, gc_details, generate, change - gopls commands: e.g. fillstruct, organize imports, list modules, list packages, gc_details, generate, change
signature, etc. signature, etc.
- Runtime lint/vet/compile: Supported by LSP (once you set up your LSP client), GoLint with golangci-lint also supported - Runtime lint/vet/compile: Supported by LSP (once you set up your LSP client), GoLint with golangci-lint also supported
- Build/Make/Test: Go.nvim provides support for these by an async job wrapper. - Build/Make/Test: Go.nvim provides support for these by an async job wrapper.
- Test coverage: run test coverage and show coverage sign and function metrics - Test coverage: run test coverage and show coverage sign and function metrics
- Dlv Debug: with [nvim-dap](https://github.com/mfussenegger/nvim-dap) and [Dap UI](https://github.com/rcarriga/nvim-dap-ui). Go adapter included, zero config for your debug setup. - Dlv Debug: with [nvim-dap](https://github.com/mfussenegger/nvim-dap) and
[Dap UI](https://github.com/rcarriga/nvim-dap-ui). Go adapter included, zero config for your debug setup.
- Load vscode launch configuration - Load vscode launch configuration
- Unit test: generate unit test framework with [gotests](https://github.com/cweill/gotests). Run test with - Unit test: generate unit test framework with [gotests](https://github.com/cweill/gotests). Run test with
richgo/ginkgo/gotestsum/go test richgo/ginkgo/gotestsum/go test
- Add and remove tag for struct with tag modify(gomodifytags) - Add and remove tag for struct with tag modify(gomodifytags)
- Code format: Supports LSP format and GoFmt(with golines) - Code format: Supports LSP format and GoFmt(with golines)
- CodeLens : gopls codelens and codelens action support - CodeLens : gopls codelens and codelens action support
- Comments: Add autodocument for your package/function/struct/interface. This feature is unique and can help you suppress golint - Comments: Add autodocument for your package/function/struct/interface. This feature is unique and can help you
errors... suppress golint errors...
- Go to alternative go file (between test and source) - Go to alternative go file (between test and source)
- Test with ginkgo, richgo inside floaterm (to enable floaterm, guihua.lua has to be installed) - Test with ginkgo, richgo inside floaterm (to enable floaterm, guihua.lua has to be installed)
- Code refactor made easy: GoFixPlural, FixStruct, FixSwitch, Add comment, IfErr, ModTidy, GoGet, extract function/block with codeactions... Most of the tools are built on top of - Code refactor made easy: GoFixPlural, FixStruct, FixSwitch, Add comment, IfErr, ModTidy, GoGet, extract function/block
treesitter AST or go AST. Fast and accurate. with codeactions... Most of the tools are built on top of treesitter AST or go AST. Fast and accurate.
- GoCheat get go cheatsheet from [cheat.sh](https://cheat.sh/). - GoCheat get go cheatsheet from [cheat.sh](https://cheat.sh/).
- Smart build tag detection when debug/run tests (e.g. `//go:build integration`) - Smart build tag detection when debug/run tests (e.g. `//go:build integration`)
- Generate mocks with mockgen - Generate mocks with mockgen
@ -45,10 +49,9 @@ signature, etc.
## Installation ## Installation
Use your favorite package manager to install. The dependency ` treesitter ` (and optionally, treesitter-objects) Use your favorite package manager to install. The dependency `treesitter` (and optionally, treesitter-objects) should be
should be installed the first time you use it. installed the first time you use it. Also Run `TSInstall go` to install the go parser if not installed yet. `sed` is
Also Run `TSInstall go` to install the go parser if not installed yet. recommended to run this plugin.
`sed` is recommended to run this plugin.
### [vim-plug](https://github.com/junegunn/vim-plug) ### [vim-plug](https://github.com/junegunn/vim-plug)
@ -85,7 +88,6 @@ use 'nvim-treesitter/nvim-treesitter'
ft = {"go", 'gomod'}, ft = {"go", 'gomod'},
build = ':lua require("go.install").update_all_sync()' -- if you need to install/update all binaries build = ':lua require("go.install").update_all_sync()' -- if you need to install/update all binaries
} }
``` ```
The go.nvim load speed is fast and you can enable it by default The go.nvim load speed is fast and you can enable it by default
@ -111,7 +113,7 @@ local format_sync_grp = vim.api.nvim_create_augroup("GoFormat", {})
vim.api.nvim_create_autocmd("BufWritePre", { vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.go", pattern = "*.go",
callback = function() callback = function()
require('go.format').goimport() require('go.format').goimports()
end, end,
group = format_sync_grp, group = format_sync_grp,
}) })
@ -157,13 +159,11 @@ To close the floating term.
## refactor gorename ## refactor gorename
gorename as an alternative to gopls rename as it supports rename across packages gorename as an alternative to gopls rename as it supports rename across packages Note: use with care Command: GoRename
Note: use with care
Command: GoRename
## code format ## code format
nvim-lsp support goimport by default. nvim-lsp support goimports by default.
```vim ```vim
autocmd BufWritePre (InsertLeave?) <buffer> lua vim.lsp.buf.formatting_sync(nil,500) autocmd BufWritePre (InsertLeave?) <buffer> lua vim.lsp.buf.formatting_sync(nil,500)
@ -175,7 +175,7 @@ Use following code to format go code
```lua ```lua
require("go.format").gofmt() -- gofmt only require("go.format").gofmt() -- gofmt only
require("go.format").goimport() -- goimport + gofmt require("go.format").goimports() -- goimports + gofmt
``` ```
### Format on save ### Format on save
@ -195,25 +195,21 @@ vim.api.nvim_create_autocmd("BufWritePre", {
end, end,
group = format_sync_grp, group = format_sync_grp,
}) })
``` ```
#### Run gofmt + goimport on save #### Run gofmt + goimports on save
```lua ```lua
-- Run gofmt + goimport on save -- Run gofmt + goimports on save
local format_sync_grp = vim.api.nvim_create_augroup("GoImport", {}) local format_sync_grp = vim.api.nvim_create_augroup("goimports", {})
vim.api.nvim_create_autocmd("BufWritePre", { vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.go", pattern = "*.go",
callback = function() callback = function()
require('go.format').goimport() require('go.format').goimports()
end, end,
group = format_sync_grp, group = format_sync_grp,
}) })
``` ```
## Auto-fill ## Auto-fill
@ -242,11 +238,11 @@ func Foo() (io.Reader, error) { // the cursor on this line to add if err stateme
## Textobject ## Textobject
Supported by treesitter. TS provided better parse result compared to regular expression. Supported by treesitter. TS provided better parse result compared to regular expression. See the example
See the example [treesitter config file](https://github.com/ray-x/go.nvim#text-object) on how to setup [treesitter config file](https://github.com/ray-x/go.nvim#text-object) on how to setup textobjects. Also with
textobjects. Also with treesitter-objects, you can move, swap the selected blocks of codes, which is fast and accurate. treesitter-objects, you can move, swap the selected blocks of codes, which is fast and accurate. `go.nvim` will load
`go.nvim` will load textobject with treesiteter, with default keybindings, if you what to set it up yourself, you can textobject with treesiteter, with default keybindings, if you what to set it up yourself, you can set `textobject` to
set `textobject` to false. false.
## Go binaries install and update ## Go binaries install and update
@ -269,8 +265,9 @@ The following go binaries are used in `go.nvim` (depends on your setup):
- govulncheck - govulncheck
- goenum - goenum
If you run `GoFmt` and the configured binary (e.g. golines) was not installed, the plugin will install it for you. But the If you run `GoFmt` and the configured binary (e.g. golines) was not installed, the plugin will install it for you. But
first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install all binaries before using the plugin. the first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install all binaries before using the
plugin.
| command | Description | | command | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
@ -297,9 +294,9 @@ first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install
| GoTest -n | test nearest, see GoTestFunc | | GoTest -n | test nearest, see GoTestFunc |
| GoTest -f | test current file, see GoTestFile | | GoTest -f | test current file, see GoTestFile |
| GoTest -n 1 | -count=1 flag | | GoTest -n 1 | -count=1 flag |
| GoTest -p {pkgname} | test package, see GoTestPkg, test current package if {pkgname} not specified | | GoTest -p {pkgname} | test package, see GoTestPkg, test current package if {pkgname} not specified |
| GoTest -parallel {number} | test current package with parallel number | | GoTest -parallel {number} | test current package with parallel number |
| GoTest -b {build_flags} | run `go test` with build flags e.g. `-gcflags=.` | | GoTest -b {build_flags} | run `go test` with build flags e.g. `-gcflags=.` |
| GoTest -t yourtags | go test ./... -tags=yourtags, see notes | | GoTest -t yourtags | go test ./... -tags=yourtags, see notes |
| GoTest -a your_args | go test ./... -args=yourargs, see notes | | GoTest -a your_args | go test ./... -args=yourargs, see notes |
| GoTest package_path -t yourtags | go test packagepath -tags=yourtags | | GoTest package_path -t yourtags | go test packagepath -tags=yourtags |
@ -307,7 +304,7 @@ first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install
| GoLint | golangci-lint | | GoLint | golangci-lint |
| GoGet {package_url} | go get package_url and restart gopls. Note1 | | GoGet {package_url} | go get package_url and restart gopls. Note1 |
| GoVet | go vet | | GoVet | go vet |
| GoWork {run|use} {pkgpath} | go work {run|use} pkgpath | | GoWork {run | use} {pkgpath} |
| GoCoverage | go test -coverprofile | | GoCoverage | go test -coverprofile |
| GoCoverage -p | go test -coverprofile (only tests package for current buffer) | | GoCoverage -p | go test -coverprofile (only tests package for current buffer) |
| GoCoverage -f coverage_file_name | load coverage file | | GoCoverage -f coverage_file_name | load coverage file |
@ -317,8 +314,8 @@ first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install
Note: Note:
1. if package_url not provided, will check current line is a valid package url or not, if it is valid, will 1. if package_url not provided, will check current line is a valid package url or not, if it is valid, will fetch
fetch current url current url
2. tags: if `//+build tags` exist it will be added automatically 2. tags: if `//+build tags` exist it will be added automatically
3. args: if multiple args is provided, you need toconcatenate it with '\ ', e.g. GoTest -a yourtags\ other_args 3. args: if multiple args is provided, you need toconcatenate it with '\ ', e.g. GoTest -a yourtags\ other_args
4. % will expand to current file path, e.g. GoBuild % 4. % will expand to current file path, e.g. GoBuild %
@ -327,9 +324,8 @@ Show test coverage:
<img width="479" alt="GoTestCoverage" src="https://user-images.githubusercontent.com/1681295/130821038-fa2545c6-16f6-4448-9a0c-91a1ab333750.png"> <img width="479" alt="GoTestCoverage" src="https://user-images.githubusercontent.com/1681295/130821038-fa2545c6-16f6-4448-9a0c-91a1ab333750.png">
Provided wrapper for gobulild/test etc with async make Provided wrapper for gobulild/test etc with async make Also suggest to use
Also suggest to use [vim-test](https://github.com/vim-test/vim-test), which can run running tests on different [vim-test](https://github.com/vim-test/vim-test), which can run running tests on different granularities.
granularities.
## Unit test with [gotests](https://github.com/cweill/gotests) and testify ## Unit test with [gotests](https://github.com/cweill/gotests) and testify
@ -367,7 +363,8 @@ GoTestXXX Arguments
Note: For GoTestXXX Note: For GoTestXXX
You can add available arguments with long name or character flag e.g. `GoTest -tags=integration ./internal/web -b=. -count=1 -` You can add available arguments with long name or character flag e.g.
`GoTest -tags=integration ./internal/web -b=. -count=1 -`
You can also add other unmapped arguments after the `-a` or `-args` flag `GoTest -a mock=true` You can also add other unmapped arguments after the `-a` or `-args` flag `GoTest -a mock=true`
@ -385,17 +382,14 @@ If no argument provided, fallback to lsp.hover()
## GoPkgOutline ## GoPkgOutline
A symbole outline for all symbols (var, const, func, struct, interface etc) inside a package A symbole outline for all symbols (var, const, func, struct, interface etc) inside a package You can still use navigator
You can still use navigator or sidebar plugins (e.g. vista, symbols-outline) to check outline within a file. But it or sidebar plugins (e.g. vista, symbols-outline) to check outline within a file. But it is more useful for go to check
is more useful for go to check the symbols in a package, as those symbols are visuals inside package, also the the symbols in a package, as those symbols are visuals inside package, also the method can be defined in different
method can be defined in different source file. source file.
Command format: Command format: GoPkgOutline {options} options: -f: show in floatwing window (default side panel, both require
GoPkgOutline {options} quihua.lua) -p package_name: the package you want to list. e.g. GoPkgOutline -p json; default package is current file's
options: package If guihua not installed fallback to loclist
-f: show in floatwing window (default side panel, both require quihua.lua)
-p package_name: the package you want to list. e.g. GoPkgOutline -p json; default package is current file's package
If guihua not installed fallback to loclist
<img width="902" alt="image" src="https://user-images.githubusercontent.com/1681295/175231905-82df4e4b-a508-4bb8-b878-9f0029643005.png"> <img width="902" alt="image" src="https://user-images.githubusercontent.com/1681295/175231905-82df4e4b-a508-4bb8-b878-9f0029643005.png">
@ -409,20 +403,17 @@ Modify struct tags by [`gomodifytags`](https://github.com/fatih/gomodifytags) an
| GoRmTag | | | GoRmTag | |
| GoClearTag | | | GoClearTag | |
Options: Options: -transform/-t: transform the tag -add-options/-a: add options to the tag
-transform/-t: transform the tag
-add-options/-a: add options to the tag
## GoFmt ## GoFmt
nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumpt (stricter version of nvim-lsp support goimports by default. The plugin provided a new formatter, goline + gofumpt (stricter version of gofmt)
gofmt)
| command | Description | | command | Description |
| --------------------- | ------------------------ | | ---------------------- | ------------------------ |
| GoFmt {opts} | default: gofumpt | | GoFmt {opts} | default: gofumpt |
| GoImport | default: goimport | | GoImports | default: goimports |
| GoImport package_path | gopls add_import package | | GoImports package_path | gopls add_import package |
{opts} : `-a` format all buffers {opts} : `-a` format all buffers
@ -487,12 +478,13 @@ or simply your cursor on a interface and specify a receiver type
Notes: Notes:
1. Without any argument, will check if launch.json existed or not, if existed, using launch.json and popup input. 1. Without any argument, will check if launch.json existed or not, if existed, using launch.json and popup input. If
If launch.json not existed, will start debug session for current file, if current file is package main will run launch.json not existed, will start debug session for current file, if current file is package main will run main(),
main(), else will start the debug package test else will start the debug package test
2. with -t option, if the current file is not a test file, will switch to the test file and run test for current function 2. with -t option, if the current file is not a test file, will switch to the test file and run test for current
3. If the cursor is inside scope of a test function, will debug the current test function, if cursor is inside a test file, will debug function
current test file 3. If the cursor is inside scope of a test function, will debug the current test function, if cursor is inside a test
file, will debug current test file
## Switch between go and test file ## Switch between go and test file
@ -504,15 +496,10 @@ Notes:
## Go Mock ## Go Mock
go mock with mockgen is supported go mock with mockgen is supported | command | Description | | ---------------- |
| command | Description | ------------------------------------------------------- | | GoMockGen | default: generate mocks for current file |
| ---------------- | ------------------------------------------------------- | options: -s source mode(default) -i interface mode, provide interface name or put the cursor on interface -p package
| GoMockGen | default: generate mocks for current file | name default: mocks -d destination directory, default: ./mocks
options:
-s source mode(default)
-i interface mode, provide interface name or put the cursor on interface
-p package name default: mocks
-d destination directory, default: ./mocks
## Comments and Doc ## Comments and Doc
@ -525,7 +512,7 @@ type GoLintComplaining struct{}
And run And run
```lua ```lua
lua.require('go.comment').gen() -- or your favorite key binding and setup placeholder "no more complaint ;P" lua.require('go.comment').gen() -- or your favorite key binding and setup placeholder "no more complaint ;P"
``` ```
The code will be: The code will be:
@ -552,9 +539,9 @@ run `go mod tidy` and restart gopls
## LSP ## LSP
Nvim-lsp is good enough for a gopher. If you looking for a better GUI. You can install Nvim-lsp is good enough for a gopher. If you looking for a better GUI. You can install
[navigator](https://github.com/ray-x/navigator.lua), or lspsaga, and lsp-utils etc. [navigator](https://github.com/ray-x/navigator.lua), or lspsaga, and lsp-utils etc. The goal of go.nvim is more provide
The goal of go.nvim is more provide unique functions releated to gopls instead of a general lsp gui client. unique functions releated to gopls instead of a general lsp gui client. The lsp config in go.nvim has a none default
The lsp config in go.nvim has a none default setup and contains some improvement and I would suggest you to use. setup and contains some improvement and I would suggest you to use.
## LSP cmp support ## LSP cmp support
@ -570,18 +557,17 @@ require('go').setup({
-- other setups -- other setups
}, },
}) })
``` ```
## LSP CodeLens ## LSP CodeLens
Gopls supports code lens. To run gopls code lens action `GoCodeLenAct` Gopls supports code lens. To run gopls code lens action `GoCodeLenAct` Note: codelens need to be enabled in gopls, check
Note: codelens need to be enabled in gopls, check default config in default config in
## LSP CodeActions ## LSP CodeActions
You can use native code action provided by lspconfig. If you installed guihua, you can also use a GUI version of You can use native code action provided by lspconfig. If you installed guihua, you can also use a GUI version of code
code action `GoCodeAction` action `GoCodeAction`
## Lint ## Lint
@ -590,11 +576,10 @@ configure it with ALE
## Debug with dlv ## Debug with dlv
Setup(adapter) for go included. Need Dap and Dap UI plugin Setup(adapter) for go included. Need Dap and Dap UI plugin [nvim-dap](https://github.com/mfussenegger/nvim-dap)
[nvim-dap](https://github.com/mfussenegger/nvim-dap)
[nvim-dap-ui](https://github.com/rcarriga/nvim-dap-ui) [nvim-dap-ui](https://github.com/rcarriga/nvim-dap-ui)
![dap](https://user-images.githubusercontent.com/1681295/125160289-743ba080-e1bf-11eb-804f-6a6d227ec33b.jpg) ![dap](https://user-images.githubusercontent.com/1681295/125160289-743ba080-e1bf-11eb-804f-6a6d227ec33b.jpg) GDB style
GDB style key mapping is used key mapping is used
### Keymaps ### Keymaps
@ -615,9 +600,8 @@ GDB style key mapping is used
### Moving from vscode-go debug ### Moving from vscode-go debug
Please check [Vscode Launch configurations](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) Please check [Vscode Launch configurations](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations)
for more info for more info go.nvim support launch debuger from vscode-go .vscode/launch.json configurations If launch.json is valid,
go.nvim support launch debuger from vscode-go .vscode/launch.json configurations run `GoDebug` will launch from the launch.json configuration.
If launch.json is valid, run `GoDebug` will launch from the launch.json configuration.
### Inlay hints ### Inlay hints
@ -638,22 +622,18 @@ Here is a sample [launch.json](https://github.com/ray-x/go.nvim/blob/master/play
### Json to Go struct ### Json to Go struct
- ["x]GoJson2Struct! - ["x]GoJson2Struct! Visual select the json and run `GoJson2Struct youStructName` -bang will put result to register `a`
Visual select the json and run `GoJson2Struct youStructName`
-bang will put result to register `a`
if ["x] specified, will put get json from clipboard if ["x] specified, will put get json from clipboard
### Load Env file ### Load Env file
- GoEnv {filename} - GoEnv {filename} By default load .env file in current directory, if you want to load other file, use {filename} option
By default load .env file in current directory, if you want to load other file, use {filename} option
### Generate return value ### Generate return value
- GoGenReturn - GoGenReturn
create return value for current function create return value for current function e.g. if we have
e.g. if we have
```go ```go
func Foo() (int, error) { func Foo() (int, error) {
@ -678,28 +658,23 @@ if err != nil {
### Rename modules ### Rename modules
- Gomvp - Gomvp Rename module name in under cursor e.g. Gomvp Gomvp old_mod_name Gomvp old_mod_name new_mod_name
Rename module name in under cursor
e.g.
Gomvp
Gomvp old_mod_name
Gomvp old_mod_name new_mod_name
### govulncheck ### govulncheck
- GoVulnCheck {arguments} - GoVulnCheck {arguments} Run govulncheck on current project
Run govulncheck on current project
### goenum ### goenum
- Goenum {arguments} - Goenum {arguments} Run goenum on current project
Run goenum on current project
### gonew ### gonew
- GoNew {filename} - GoNew {filename} Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will create string.go
Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will create string.go with template file with template file GoNew also support using `gonew` command to create new file with template file
GoNew also support using `gonew` command to create new file with template file [gonew cli](https://go.dev/blog/gonew), e.g `GoNew hello package_name/folder` is same as `gonew golang.org/x/example/hello package_name/folder` if package_name/folder not provided, a hello project will be created in current folder [gonew cli](https://go.dev/blog/gonew), e.g `GoNew hello package_name/folder` is same as
`gonew golang.org/x/example/hello package_name/folder` if package_name/folder not provided, a hello project will be
created in current folder
### ginkgo ### ginkgo
@ -745,11 +720,10 @@ Also you can check telescope dap extension : nvim-telescope/telescope-dap.nvim
Sample vimrc for DAP Sample vimrc for DAP
```viml ```viml
Plug 'mfussenegger/nvim-dap' Plug 'mfussenegger/nvim-dap'
Plug 'rcarriga/nvim-dap-ui' Plug 'rcarriga/nvim-dap-ui'
Plug 'theHamsta/nvim-dap-virtual-text' Plug 'theHamsta/nvim-dap-virtual-text'
" Plug 'nvim-telescope/telescope-dap.nvim' " Plug 'nvim-telescope/telescope-dap.nvim'
``` ```
## Commands ## Commands
@ -778,8 +752,8 @@ require('go').setup({
disable_defaults = false, -- true|false when true set false to all boolean settings and replace all table disable_defaults = false, -- true|false when true set false to all boolean settings and replace all table
-- settings with {} -- settings with {}
go='go', -- go command, can be go[default] or go1.18beta1 go='go', -- go command, can be go[default] or go1.18beta1
goimport='gopls', -- goimport command, can be gopls[default] or either goimport or golines if need to split long lines goimports ='gopls', -- goimports command, can be gopls[default] or either goimports or golines if need to split long lines
gofmt = 'gofumpt', --gofmt cmd, gofmt = 'gopls', -- gofmt through gopls: alternative is gofumpt, goimports, golines, gofmt, etc
max_line_len = 0, -- max line length in golines format, Target maximum line length for golines max_line_len = 0, -- max line length in golines format, Target maximum line length for golines
tag_transform = false, -- can be transform option("snakecase", "camelcase", etc) check gomodifytags for details and more options tag_transform = false, -- can be transform option("snakecase", "camelcase", etc) check gomodifytags for details and more options
tag_options = 'json=omitempty', -- sets options sent to gomodifytags, i.e., json=omitempty tag_options = 'json=omitempty', -- sets options sent to gomodifytags, i.e., json=omitempty
@ -792,7 +766,8 @@ require('go').setup({
-- false: do nothing -- false: do nothing
-- if lsp_cfg is a table, merge table with with non-default gopls setup in go/lsp.lua, e.g. -- if lsp_cfg is a table, merge table with with non-default gopls setup in go/lsp.lua, e.g.
-- lsp_cfg = {settings={gopls={matcher='CaseInsensitive', ['local'] = 'your_local_module_path', gofumpt = true }}} -- lsp_cfg = {settings={gopls={matcher='CaseInsensitive', ['local'] = 'your_local_module_path', gofumpt = true }}}
lsp_gofumpt = false, -- true: set default gofmt in gopls format to gofumpt lsp_gofumpt = true, -- true: set default gofmt in gopls format to gofumpt
-- false: do not set default gofmt in gopls format to gofumpt
lsp_on_attach = nil, -- nil: use on_attach function defined in go/lsp.lua, lsp_on_attach = nil, -- nil: use on_attach function defined in go/lsp.lua,
-- when lsp_cfg is true -- when lsp_cfg is true
-- if lsp_on_attach is a function: use this function as on_attach function for gopls -- if lsp_on_attach is a function: use this function as on_attach function for gopls
@ -887,12 +862,11 @@ require('go').setup({
}) })
``` ```
You will need to add keybind yourself: You will need to add keybind yourself: e.g
e.g
```lua ```lua
vim.cmd("autocmd FileType go nmap <Leader><Leader>l GoLint") vim.cmd("autocmd FileType go nmap <Leader><Leader>l GoLint")
vim.cmd("autocmd FileType go nmap <Leader>gc :lua require('go.comment').gen()") vim.cmd("autocmd FileType go nmap <Leader>gc :lua require('go.comment').gen()")
``` ```
## Project setup ## Project setup
@ -907,7 +881,7 @@ vim.g.null_ls_disable = true
return { return {
go = "go", -- set to go1.18beta1 if necessary go = "go", -- set to go1.18beta1 if necessary
goimport = "gopls", -- if set to 'gopls' will use gopls format, also goimport goimports = "gopls", -- if set to 'gopls' will use gopls format, also goimports
gofmt = "gofumpt", -- if set to gopls will use gopls format gofmt = "gofumpt", -- if set to gopls will use gopls format
null_ls_document_formatting_disable = true null_ls_document_formatting_disable = true
} }
@ -917,8 +891,7 @@ This will override your global `go.nvim` setup
## Text object ## Text object
I did not provide textobject support in the plugin. Please use treesitter textobject plugin. I did not provide textobject support in the plugin. Please use treesitter textobject plugin. My treesitter config:
My treesitter config:
```lua ```lua
require "nvim-treesitter.configs".setup { require "nvim-treesitter.configs".setup {
@ -1015,26 +988,33 @@ My treesitter config:
} }
} }
``` ```
</details> </details>
## LuaSnip supports ## LuaSnip supports
go.nvim provides a better snippet support for go. go.nvim provides a better snippet support for go. Please check
Please check [snippets for all languages](https://github.com/ray-x/go.nvim/blob/master/lua/snips/all.lua) [snippets for all languages](https://github.com/ray-x/go.nvim/blob/master/lua/snips/all.lua) and
and [snippets for go](https://github.com/ray-x/go.nvim/blob/master/lua/snips/go.lua) [snippets for go](https://github.com/ray-x/go.nvim/blob/master/lua/snips/go.lua)
For a video demo, please check this: For a video demo, please check this: [go.nvim new features work through](https://www.youtube.com/watch?v=tsLnEfYTgcM)
[go.nvim new features work through](https://www.youtube.com/watch?v=tsLnEfYTgcM)
If you are not familiar with luasnip, please checkout [LuaSnip Tutorial](https://www.youtube.com/watch?v=ub0REXjhpmk) and [TJ's Introduction to LuaSnip](https://www.youtube.com/watch?v=Dn800rlPIho) If you are not familiar with luasnip, please checkout [LuaSnip Tutorial](https://www.youtube.com/watch?v=ub0REXjhpmk)
and [TJ's Introduction to LuaSnip](https://www.youtube.com/watch?v=Dn800rlPIho)
## Nvim LSP setup ## Nvim LSP setup
go.nvim provided a better non-default setup for gopls (includes debounce, staticcheck, diagnosticsDelay etc) go.nvim provided a better non-default setup for gopls (includes debounce, staticcheck, diagnosticsDelay etc)
This gopls setup provided by go.nvim works perfectly fine for most of the cases. You can also install [navigator.lua](https://github.com/ray-x/navigator.lua) which can auto setup all lsp clients and provides a better GUI. This gopls setup provided by go.nvim works perfectly fine for most of the cases. You can also install
[navigator.lua](https://github.com/ray-x/navigator.lua) which can auto setup all lsp clients and provides a better GUI.
For diagnostic issue, you can use the default setup. There are also quite a few plugins that you can use to explore
issues, e.g. [navigator.lua](https://github.com/ray-x/navigator.lua),
[folke/lsp-trouble.nvim](https://github.com/folke/lsp-trouble.nvim).
[Nvim-tree](https://github.com/kyazdani42/nvim-tree.lua) and
[Bufferline](https://github.com/akinsho/nvim-bufferline.lua) also introduced lsp diagnostic hooks.
For diagnostic issue, you can use the default setup. There are also quite a few plugins that you can use to explore issues, e.g. [navigator.lua](https://github.com/ray-x/navigator.lua), [folke/lsp-trouble.nvim](https://github.com/folke/lsp-trouble.nvim). [Nvim-tree](https://github.com/kyazdani42/nvim-tree.lua) and [Bufferline](https://github.com/akinsho/nvim-bufferline.lua) also introduced lsp diagnostic hooks.
<details> <details>
<summary>Gopls default settings in go.nvim</summary> <summary>Gopls default settings in go.nvim</summary>
@ -1144,8 +1124,8 @@ gopls = {
end, end,
}, },
} }
``` ```
</details> </details>
## Integrate with mason-lspconfig ## Integrate with mason-lspconfig
@ -1163,7 +1143,6 @@ require('lspconfig').gopls.setup({
If you want to use gopls setup provided by go.nvim If you want to use gopls setup provided by go.nvim
```lua ```lua
-- setup your go.nvim -- setup your go.nvim
-- make sure lsp_cfg is disabled -- make sure lsp_cfg is disabled
require("mason").setup() require("mason").setup()
@ -1175,12 +1154,12 @@ require('go').setup{
local cfg = require'go.lsp'.config() -- config() return the go.nvim gopls setup local cfg = require'go.lsp'.config() -- config() return the go.nvim gopls setup
require('lspconfig').gopls.setup(cfg) require('lspconfig').gopls.setup(cfg)
``` ```
## Highlighting for gomod, gosum, gohtmltmpl, gotmpl, gotexttmpl ## Highlighting for gomod, gosum, gohtmltmpl, gotmpl, gotexttmpl
You can install treesitter parser for gomod and gosum You can install treesitter parser for gomod and gosum
```vim ```vim
:TSInstall gomod gosum :TSInstall gomod gosum
``` ```
@ -1210,7 +1189,6 @@ The plugin injects the tmpl to html syntax so you should see this:
![image](https://github.com/ray-x/go.nvim/assets/1681295/7d11eb96-4803-418b-b056-336163ed492b) ![image](https://github.com/ray-x/go.nvim/assets/1681295/7d11eb96-4803-418b-b056-336163ed492b)
## Integrate null-ls ## Integrate null-ls
### The plugin provides: ### The plugin provides:
@ -1243,7 +1221,6 @@ null_ls.setup({ sources = sources, debounce = 1000, default_timeout = 5000 })
-- alternatively -- alternatively
null_ls.register(gotest) null_ls.register(gotest)
``` ```
You will see the failed tests flagged You will see the failed tests flagged
@ -1271,7 +1248,7 @@ call plug#end()
lua <<EOF lua <<EOF
require 'go'.setup({ require 'go'.setup({
goimport = 'gopls', -- if set to 'gopls' will use golsp format goimports = 'gopls', -- if set to 'gopls' will use golsp format
gofmt = 'gopls', -- if set to gopls will use golsp format gofmt = 'gopls', -- if set to gopls will use golsp format
tag_transform = false, tag_transform = false,
test_dir = '', test_dir = '',

@ -103,7 +103,7 @@ BINARIES *go-nvim-binaries*
golint `golangci-lint` golint `golangci-lint`
gotags gotags
golines golines
goimport goimports
settings below will take effect (so you'll need to use settings below will take effect (so you'll need to use
@ -168,7 +168,7 @@ COMMANDS *go-nvim-commands*
au Syntax go hi goCoverageCovered guibg=green au Syntax go hi goCoverageCovered guibg=green
au Syntax go hi goCoverageUncover guibg=brown au Syntax go hi goCoverageUncover guibg=brown
augroup end augroup end
:GoImport {package_name} *:GoImport* :GoImports {package_name} *:GoImports*
Add, modify imports. Add, modify imports.
:GoBuild {-tags=tagname}{package_name} *:GoBuild* :GoBuild {-tags=tagname}{package_name} *:GoBuild*
@ -372,7 +372,7 @@ OPTIONS *go-nvim-options*
You can setup go.nvim with following options: You can setup go.nvim with following options:
{ {
goimport = "gopls", -- if set to 'gopls' will use gopls format, also goimport goimports = "gopls", -- if set to 'gopls' will use gopls format, also goimports
fillstruct = "gopls", fillstruct = "gopls",
gofmt = "gofumpt", -- if set to gopls will use gopls format gofmt = "gofumpt", -- if set to gopls will use gopls format
max_line_len = 120, max_line_len = 120,

@ -7,9 +7,9 @@ local vfn = vim.fn
_GO_NVIM_CFG = { _GO_NVIM_CFG = {
disable_defaults = false, -- either true when true disable all default settings disable_defaults = false, -- either true when true disable all default settings
go = 'go', -- set to go1.18beta1 if necessary go = 'go', -- set to go1.18beta1 if necessary
goimport = 'gopls', -- if set to 'gopls' will use gopls format, also goimport goimports = 'gopls', -- if set to 'gopls' will use gopls format, also goimports
fillstruct = 'gopls', fillstruct = 'gopls',
gofmt = 'gofumpt', -- if set to gopls will use gopls format gofmt = 'gopls', -- if set to gopls will use gopls format
max_line_len = 0, max_line_len = 0,
tag_transform = false, tag_transform = false,
tag_options = 'json=omitempty', tag_options = 'json=omitempty',
@ -167,6 +167,10 @@ function go.setup(cfg)
vim.log.levels.WARN vim.log.levels.WARN
) )
end end
if cfg.goimport ~= nil then
vim.notify('go.nvim goimport deprecated, use goimports', vim.log.levels.WARN)
cfg.goimports = cfg.goimport
end
if cfg.lsp_diag_virtual_text ~= nil then if cfg.lsp_diag_virtual_text ~= nil then
vim.notify( vim.notify(
'go.nvim lsp_diag_virtual_text deprecated, use diagnostic.virtual_text', 'go.nvim lsp_diag_virtual_text deprecated, use diagnostic.virtual_text',

@ -136,7 +136,12 @@ return {
end, { nargs = '*' }) end, { nargs = '*' })
create_cmd('GoImport', function(opts) create_cmd('GoImport', function(opts)
require('go.format').goimport(unpack(opts.fargs)) vim.notify('GoImport is deprecated, use GoImports' )
require('go.format').goimports(unpack(opts.fargs))
end, {
})
create_cmd('GoImports', function(opts)
require('go.format').goimports(unpack(opts.fargs))
end, { end, {
complete = function(a, l) complete = function(a, l)
return package.loaded.go.doc_complete(a, l) return package.loaded.go.doc_complete(a, l)

@ -91,7 +91,7 @@ local run = function(fmtargs, bufnr, cmd)
end end
old_lines = nil old_lines = nil
vim.defer_fn(function() vim.defer_fn(function()
if cmd == 'goimport' then if cmd == 'goimports' then
return M.lsp_format() return M.lsp_format()
end end
if vfn.getbufinfo('%')[1].changed == 1 then if vfn.getbufinfo('%')[1].changed == 1 then
@ -151,11 +151,12 @@ M.org_imports = function()
require('go.lsp').codeaction('', 'source.organizeImports', M.gofmt) require('go.lsp').codeaction('', 'source.organizeImports', M.gofmt)
end end
M.goimport = function(...)
local goimport = _GO_NVIM_CFG.goimport or 'gopls' M.goimports = function(...)
local goimports = _GO_NVIM_CFG.goimports or 'gopls'
local args = { ... } local args = { ... }
log(args, goimport) log(args, goimports)
if goimport == 'gopls' then if goimports == 'gopls' then
if vfn.empty(args) == 1 then if vfn.empty(args) == 1 then
return M.org_imports() return M.org_imports()
else else
@ -165,7 +166,7 @@ M.goimport = function(...)
end end
end end
local buf = vim.api.nvim_get_current_buf() local buf = vim.api.nvim_get_current_buf()
require('go.install').install(goimport) require('go.install').install(goimports)
-- specified the pkg name -- specified the pkg name
if #args > 0 then -- dont use golines if #args > 0 then -- dont use golines
return run(args, buf, 'goimports') return run(args, buf, 'goimports')
@ -173,10 +174,11 @@ M.goimport = function(...)
-- golines base formatter is goimports -- golines base formatter is goimports
local a = {} local a = {}
if goimport == 'golines' then if goimports == 'golines' then
a = vim.deepcopy(goimport_args) a = vim.deepcopy(goimport_args)
end end
run(a, buf, goimport) run(a, buf, goimports)
end end
M.goimports = M.goimports
return M return M

@ -3,7 +3,7 @@
-- sample cfg -- sample cfg
return { return {
go = "go", -- set to go1.18beta1 if necessary go = "go", -- set to go1.18beta1 if necessary
goimport = "gopls", -- if set to 'gopls' will use gopls format, also goimport goimports = "gopls", -- if set to 'gopls' will use gopls format, also goimports
gofmt = "gofumpt", -- if set to gopls will use gopls format gofmt = "gofumpt", -- if set to gopls will use gopls format
tag_transform = false, tag_transform = false,
test_dir = "", test_dir = "",

@ -82,10 +82,10 @@ describe('should run gofmt', function()
vim.cmd(cmd) vim.cmd(cmd)
vim.cmd([[packadd go.nvim]]) vim.cmd([[packadd go.nvim]])
require('go').setup({ goimport = 'goimports' }) require('go').setup({ goimports = 'goimports' })
_GO_NVIM_CFG.goimport = 'goimports' _GO_NVIM_CFG.goimports = 'goimports'
vim.cmd([[cd %:p:h]]) vim.cmd([[cd %:p:h]])
require('go.format').goimport() require('go.format').goimports()
-- print('workspaces:', vim.inspect(vim.lsp.buf.list_workspace_folders())) -- print('workspaces:', vim.inspect(vim.lsp.buf.list_workspace_folders()))
vim.wait(500, function() end) vim.wait(500, function() end)
local fmt = vim.fn.join(vim.fn.readfile(name), '\n') local fmt = vim.fn.join(vim.fn.readfile(name), '\n')
@ -93,7 +93,7 @@ describe('should run gofmt', function()
cmd = 'bd! ' .. name cmd = 'bd! ' .. name
vim.cmd(cmd) vim.cmd(cmd)
end) end)
it('should run import from file with goimport with package name', function() it('should run import from file with goimports with package name', function()
local path = cur_dir .. '/lua/tests/fixtures/fmt/goimports.go' -- %:p:h ? %:p local path = cur_dir .. '/lua/tests/fixtures/fmt/goimports.go' -- %:p:h ? %:p
local expected = local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. '/lua/tests/fixtures/fmt/goimports_golden.go'), '\n') vim.fn.join(vim.fn.readfile(cur_dir .. '/lua/tests/fixtures/fmt/goimports_golden.go'), '\n')
@ -106,9 +106,9 @@ describe('should run gofmt', function()
vim.cmd([[cd %:p:h]]) vim.cmd([[cd %:p:h]])
print('code write to ' .. name) print('code write to ' .. name)
require('go').setup({ goimport = 'goimports', gofmt = 'gofmt' }) require('go').setup({ goimports = 'goimports', gofmt = 'gofmt' })
local gofmt = require('go.format') local gofmt = require('go.format')
gofmt.goimport('fmt') gofmt.goimports('fmt')
vim.wait(400, function() end) vim.wait(400, function() end)
vim.cmd([[w]]) vim.cmd([[w]])

@ -11,10 +11,10 @@ describe('should run gopls related functions', function()
it('should import time from file with gopls', function() it('should import time from file with gopls', function()
require('plenary.reload').reload_module('go.nvim') require('plenary.reload').reload_module('go.nvim')
require('go').setup({ goimport = 'gopls', verbose = true, log_path = '', lsp_cfg = true }) require('go').setup({ goimports = 'gopls', verbose = true, log_path = '', lsp_cfg = true })
local cmd = " silent exe 'e temp.go'" local cmd = " silent exe 'e temp.go'"
vim.cmd(cmd) vim.cmd(cmd)
_GO_NVIM_CFG.goimport = 'gopls' _GO_NVIM_CFG.goimports = 'gopls'
_GO_NVIM_CFG.log_path = '' -- enable log to console _GO_NVIM_CFG.log_path = '' -- enable log to console
_GO_NVIM_CFG.lsp_codelens = false _GO_NVIM_CFG.lsp_codelens = false
local expected = local expected =
@ -32,7 +32,7 @@ describe('should run gopls related functions', function()
eq(#c > 0, true) eq(#c > 0, true)
_GO_NVIM_CFG.log_path = '' -- enable log to console _GO_NVIM_CFG.log_path = '' -- enable log to console
require('go.format').goimport() require('go.format').goimports()
vim.wait(1000, function() vim.wait(1000, function()
return false return false

@ -12,7 +12,7 @@ describe('should run gopls related functions', function()
require('plenary.reload').reload_module('go.nvim') require('plenary.reload').reload_module('go.nvim')
local cmd = " silent exe 'e temp.go'" local cmd = " silent exe 'e temp.go'"
vim.cmd(cmd) vim.cmd(cmd)
require('go').setup({ goimport = 'gopls', lsp_cfg = true }) require('go').setup({ goimports = 'gopls', lsp_cfg = true })
local path = './fmt/goimports2.go' -- %:p:h ? %:p local path = './fmt/goimports2.go' -- %:p:h ? %:p
local expected = local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. '/lua/tests/fixtures/fmt/goimports2_golden.go'), '\n') vim.fn.join(vim.fn.readfile(cur_dir .. '/lua/tests/fixtures/fmt/goimports2_golden.go'), '\n')
@ -22,14 +22,14 @@ describe('should run gopls related functions', function()
cmd = " silent exe 'e " .. path .. "'" cmd = " silent exe 'e " .. path .. "'"
vim.cmd(cmd) vim.cmd(cmd)
_GO_NVIM_CFG.goimport = 'gopls' _GO_NVIM_CFG.goimports = 'gopls'
_GO_NVIM_CFG.lsp_codelens = false _GO_NVIM_CFG.lsp_codelens = false
vim.wait(1000, function() vim.wait(1000, function()
return false return false
end) end)
local c = vim.lsp.get_active_clients() local c = vim.lsp.get_active_clients()
eq(#c > 0, true) eq(#c > 0, true)
require('go.format').goimport() require('go.format').goimports()
local fmt local fmt
require('go.utils').log('workspaces:', vim.inspect(vim.lsp.buf.list_workspace_folders())) require('go.utils').log('workspaces:', vim.inspect(vim.lsp.buf.list_workspace_folders()))
vim.wait(4000, function() vim.wait(4000, function()

@ -25,7 +25,7 @@ _G.test_close = true
require("plenary/busted") require("plenary/busted")
require("go").setup({ require("go").setup({
gofmt = 'gofumpt', gofmt = 'gofumpt',
goimport = "goimports", goimports = "goimports",
verbose = true, verbose = true,
log_path = vim.fn.expand("$HOME") .. "/tmp/gonvim.log", log_path = vim.fn.expand("$HOME") .. "/tmp/gonvim.log",
lsp_cfg = true, lsp_cfg = true,

@ -25,7 +25,7 @@ _G.test_close = true
require("plenary/busted") require("plenary/busted")
require("go").setup({ require("go").setup({
gofmt = 'gofumpt', gofmt = 'gofumpt',
goimport = "goimports", goimports = "goimports",
log_path = vim.fn.expand("$HOME") .. "/gonvim.log", log_path = vim.fn.expand("$HOME") .. "/gonvim.log",
lsp_cfg = true, lsp_cfg = true,
}) })

@ -56,6 +56,9 @@ local function load_plugins()
verbose = true, verbose = true,
-- log_path = '~/tmp/go.log', -- log_path = '~/tmp/go.log',
lsp_cfg = true, lsp_cfg = true,
goimports = 'gopls',
gofmt = 'gopls',
max_line_len = 80,
}, },
}, },
} }

@ -37,7 +37,7 @@ local function load_plugins()
config = function() config = function()
require('go').setup({ require('go').setup({
verbose = true, verbose = true,
goimport = 'gopls', goimports = 'gopls',
lsp_cfg = { lsp_cfg = {
handlers = { handlers = {
['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'double' }), ['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'double' }),

Loading…
Cancel
Save