2021-04-19 06:09:39 +00:00
# go.nvim
2021-03-10 12:15:06 +00:00
2021-07-10 13:53:33 +00:00
A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. It is written in Lua and async as much as possible.
2021-03-10 13:21:01 +00:00
PR & Suggestions welcome.
2021-03-12 02:54:08 +00:00
The plugin covers most features required for a gopher.
2021-04-19 06:16:25 +00:00
- Async jobs
2021-03-12 02:54:08 +00:00
- Syntex highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support treesitter, try
[aurora ](https://github.com/ray-x/aurora ). Also, there are quite a few listed in [awesome-neovim ](https://github.com/rockerBOO/awesome-neovim )
2021-05-07 23:36:11 +00:00
- 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 )
- Runtime lint/vet/compile: Supported by lsp (once you setup up your lsp client), GoLint with golangci-lint also supported
2021-03-12 02:54:08 +00:00
- Build/Make/Test: Go.nvim provides supports for these by an async job wrapper.
2021-07-10 11:04:24 +00:00
- Dlv Debug: with Dap UI
2021-03-12 02:54:08 +00:00
- Unit test: Support [gotests ](https://github.com/cweill/gotests )
- tag modify: Supports gomodifytags
- Code format: Supports LSP format and GoFmt
- Comments: Add autodocument for your package/function/struct/interface. This feature is unique and can help you suppress golint
errors...
2021-07-14 13:58:31 +00:00
Go to alternative go file (between test and source)
2021-03-10 12:15:06 +00:00
## install
2021-07-04 02:01:28 +00:00
make sure the `$GOPATH/bin` path is added to your `$PATH` environment variable. To check this you can run
```bash
echo $PATH | grep "$GOPATH/bin"
```
if nothing shows up, you can add the following to your shell config file
```bash
export PATH=$PATH:$GOPATH/bin
```
2021-05-07 23:36:11 +00:00
add 'ray-x/go.nvim' to your package manager, the dependency is `treesitter` (and optionally, treesitter-objects)
related binaries will be installed the first time you use it
Add format in your vimrc.
```vim
autocmd BufWritePre *.go :silent! lua require('go.format').gofmt()
```
2021-03-12 02:54:08 +00:00
To startup/setup the plugin
2021-03-10 12:15:06 +00:00
```lua
require('go').setup()
```
2021-04-19 06:09:39 +00:00
## Screenshots
### Add comments
![auto comments ](https://github.com/ray-x/files/blob/master/img/go.nvim/comment.gif?raw=true )
### Add/Remove tags
![auto tag ](https://github.com/ray-x/files/blob/master/img/go.nvim/tags.gif?raw=true )
2021-04-21 11:24:07 +00:00
## refactor gorename
2021-05-07 23:36:11 +00:00
gorename as an alternative to gopls rename as it supports rename across packages
2021-07-14 13:58:31 +00:00
Command: GoRename
2021-04-21 11:24:07 +00:00
2021-03-10 12:15:06 +00:00
## code format
nvim-lsp support goimport by default.
2021-03-10 13:21:01 +00:00
2021-03-10 12:15:06 +00:00
```vim
autocmd BufWritePre (InsertLeave?) < buffer > lua vim.lsp.buf.formatting_sync(nil,500)
```
The plugin provides code format, by default is goline + gofumports (stricter version of goimport)
The format tool is a asyn format tool in format.lua
```lua
require("go.format").gofmt()
require("go.format").goimport()
```
2021-07-15 09:18:04 +00:00
## Auto fill
2021-05-07 23:36:11 +00:00
Note: auto fill struct also supported by gopls lsp-action
2021-04-23 06:31:00 +00:00
2021-07-14 13:58:31 +00:00
| command | Description |
| ----------- | ----------- |
| GoFillStruct | auto fill struct |
| GoFillSwitch | fill switch|
2021-07-15 09:18:04 +00:00
| GoIfErr | Add if err|
```go
package foo
2021-07-14 13:58:31 +00:00
2021-07-15 09:18:04 +00:00
import "io"
func Foo() (io.Reader, error) { // the cursor on this line to add if err statement
}
```
2021-07-14 13:58:31 +00:00
2021-04-23 06:31:00 +00:00
![auto struct ](https://github.com/ray-x/files/blob/master/img/go.nvim/fstruct.gif?raw=true )
2021-03-10 12:15:06 +00:00
## Textobject
Supported by treesitter. TS provided better parse result compared to regular expression.
2021-03-12 02:54:08 +00:00
Check [my treesitter config file ](https://github.com/ray-x/dotfiles/blob/master/nvim/lua/modules/lang/treesitter.lua ) on how to setup
2021-05-07 23:36:11 +00:00
textobjects. Also with treesitter-objects, you can move, swap the selected blocks of codes, which is fast and accurate.
2021-03-10 12:15:06 +00:00
## Build and test
2021-07-14 13:58:31 +00:00
| command | Description |
| ----------- | ----------- |
| GoMake | make |
| GoBuild | |
| GoGenerate | |
| GoRun | |
| GoTest | go test ./... |
| GoLint | golangci-lint |
2021-03-12 02:54:08 +00:00
Provided wrapper for gobulild/test etc with async make
2021-05-07 23:36:11 +00:00
Also suggest to use [vim-test ](https://github.com/vim-test/vim-test ), which can run running tests on different
granularities.
2021-03-10 12:15:06 +00:00
2021-03-12 02:54:08 +00:00
## Unit test with [gotests](https://github.com/cweill/gotests) and testify
2021-03-10 12:15:06 +00:00
Support table based unit test auto generate, parse current function/method name using treesitter
2021-07-14 13:58:31 +00:00
| command | Description |
| ----------- | ----------- |
| GoTestFunc | run test for current func |
| GoAddTest | |
| GoAddExpTest | Add tests for exported funcs|
| GoAddAllTest | Add tests for all funcs |
2021-03-10 12:15:06 +00:00
## Modifytags
2021-07-14 13:58:31 +00:00
2021-03-12 02:54:08 +00:00
Modify struct tags by [`gomodifytags` ](https://github.com/fatih/gomodifytags ) and treesitter
2021-03-10 12:15:06 +00:00
2021-07-14 13:58:31 +00:00
| command | Description |
| ----------- | ----------- |
| GoAddTag | |
| GoRmTag | |
| GoClearTag | |
2021-03-10 12:15:06 +00:00
## GoFmt
nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumports (stricter version of
goimport)
2021-07-14 13:58:31 +00:00
| command | Description |
| ----------- | ----------- |
| Gofmt | goline + gofumpt |
| Goimport | goline + goimport + gofumpt |
2021-07-14 15:35:38 +00:00
## GoImpl
generate method stubs for implementing an interface
Usage:
```
:GoImpl {receiver} {interface}
```
e.g:
```
:GoImpl f *File io.Reader
```
2021-07-14 13:58:31 +00:00
## Debug
| command | Description |
| ----------- | ----------- |
| GoDebug | start debug session |
| GoDebug test | start debug session for go test file |
| GoBreakToggle | |
| GoBreakCondition | conditional break |
| GoDbgStop | Stop debug session|
2021-07-13 22:39:27 +00:00
## Swtich between go and test file
2021-07-14 13:58:31 +00:00
2021-07-13 22:39:27 +00:00
| command | Description |
| ----------- | ----------- |
| GoAlt / GoAlt! | open alternative go file (use ! to create if not exist) |
| GoAltS / GoAltS! | open alternative go file in split |
| GoAltV / GoAltV! | open alternative go file in vertical split |
2021-03-10 12:15:06 +00:00
## Comments and Doc
Auto doc (to suppress golang-lint warning), generate comments by treesitter parsing result
```go
type GoLintComplaining struct{}
```
2021-03-10 13:21:01 +00:00
2021-03-10 13:26:55 +00:00
And run
2021-03-10 12:15:06 +00:00
```lua
2021-03-10 13:26:55 +00:00
lua.require('go.comment').gen() -- or your faviourite key binding and setup placeholder "no more complaint ;P"
2021-03-10 12:15:06 +00:00
```
2021-03-10 13:21:01 +00:00
2021-03-10 12:15:06 +00:00
The code will be:
2021-03-10 13:21:01 +00:00
2021-03-10 12:15:06 +00:00
```go
// GoLintComplaining struct no more complaint ;P
type GoLintComplaining struct{}
```
## LSP
2021-05-07 23:36:11 +00:00
LSP supported by 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.
2021-03-10 12:15:06 +00:00
## Lint
2021-03-12 02:54:08 +00:00
Supported by LSP, also GoLint command (by calling golangcl-lint) if you need background golangci-lint check, you can
configure it with ALE
2021-03-10 12:15:06 +00:00
2021-07-10 11:04:24 +00:00
## Debug with dlv
Setup for Debug provided. Need Dap and Dap UI plugin
![dap ](https://user-images.githubusercontent.com/1681295/125160289-743ba080-e1bf-11eb-804f-6a6d227ec33b.jpg )
GDB style key mapping is used
### Keymaps
2021-07-13 22:39:27 +00:00
| key | Description |
2021-07-10 11:04:24 +00:00
| ----------- | ----------- |
| c | continue |
| n | next |
| s | step |
| o | stepout |
| S | cap S: stop debug |
| u | up |
| D | cap D: down |
| C | cap C: run to cursor |
| b | toggle breakpoint |
| P | cap P: pause |
| p | print, hover value (also in visual mode) |
### Commands
| Command | Description |
| ----------- | ----------- |
2021-07-10 11:10:46 +00:00
| GoDebug | Start debugger, to debug test, run `Debug test` , to add addition args run `Debug arg1 arg2` |
| GoBreakToggle | toggle break point |
2021-07-10 11:04:24 +00:00
| BreakCondition | conditional break point |
| ReplRun | dap repl run_last |
| ReplToggle | dap repl toggle |
### Required DAP plugins
The plugin will setup debugger. But you need to install
* dap
* 'mfussenegger/nvim-dap'
* dap ui (optional)
* 'rcarriga/nvim-dap-ui'
* dap virtual text (optional)
* 'theHamsta/nvim-dap-virtual-text'
Also you can check telescope dap extension : nvim-telescope/telescope-dap.nvim
Sample vimrc
```viml
Plug 'mfussenegger/nvim-dap'
Plug 'rcarriga/nvim-dap-ui'
Plug 'theHamsta/nvim-dap-virtual-text'
" Plug 'nvim-telescope/telescope-dap.nvim'
```
## Commands
Check [go.lua ](https://github.com/ray-x/go.nvim/blob/master/lua/go.lua ) on all the commands provided
2021-03-10 12:15:06 +00:00
## configuration
2021-07-12 04:25:07 +00:00
Configure from lua suggested, The default setup:
2021-03-10 13:21:01 +00:00
2021-03-10 12:15:06 +00:00
```lua
require('go').setup(cfg = {
2021-07-10 11:04:24 +00:00
goimport='gofumports', -- goimport command
gofmt = 'gofumpt', --gofmt cmd,
max_line_len = 120, -- max line length in goline format
tag_transform = false, -- tag_transfer check gomodifytags for details
2021-03-10 12:15:06 +00:00
test_template = '', -- default to testify if not set; g:go_nvim_tests_template check gotests for details
test_template_dir = '', -- default to nil if not set; g:go_nvim_tests_template_dir check gotests for details
2021-07-10 11:04:24 +00:00
comment_placeholder = '' , -- comment_placeholder your cool placeholder e.g. ﳑ
2021-03-10 12:15:06 +00:00
verbose = false, -- output loginf in messages
2021-07-12 04:25:07 +00:00
lsp_cfg = false, -- true: apply go.nvim non-default gopls setup
lsp_gofumpt = false, -- true: set default gofmt in gopls format to gofumpt
lsp_on_attach = true, -- if a on_attach function provided: attach on_attach function to gopls
-- true: will use go.nvim on_attach if true
-- nil/false do nothing
lsp_diag_hdlr = true, -- hook lsp diag handler
2021-07-10 11:04:24 +00:00
dap_debug = false, -- set to true to enable dap
dap_debug_keymap = true, -- set keymaps for debugger
dap_debug_gui = true, -- set to true to enable dap gui, highly recommand
dap_debug_vt = true, -- set to true to enable dap virtual text
2021-03-10 12:15:06 +00:00
})
```
2021-03-10 13:21:01 +00:00
You will need to add keybind yourself:
e.g
```lua
vim.cmd("autocmd FileType go nmap < Leader > < Leader > l GoLint")
vim.cmd("autocmd FileType go nmap < Leader > gc :lua require('go.comment').gen()")
```
2021-07-10 11:04:24 +00:00
2021-03-10 13:26:55 +00:00
## Nvim LSP setup
2021-07-13 22:39:27 +00:00
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.
2021-05-07 23:36:11 +00:00
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.
2021-03-10 13:21:01 +00:00
2021-07-12 04:25:07 +00:00
## Sample vimrc
2021-07-13 22:39:27 +00:00
The following vimrc will enable all features provided by go.nvim
2021-03-10 13:21:01 +00:00
2021-07-12 04:25:07 +00:00
```viml
set termguicolors
call plug#begin('~/.vim/plugged')
Plug 'neovim/nvim-lspconfig'
Plug 'nvim-treesitter/nvim-treesitter'
2021-07-12 04:27:55 +00:00
Plug 'mfussenegger/nvim-dap'
Plug 'rcarriga/nvim-dap-ui'
Plug 'theHamsta/nvim-dap-virtual-text'
2021-07-12 04:25:07 +00:00
Plug 'ray-x/go.nvim'
call plug#end()
lua < < EOF
require 'go'.setup({
goimport = 'gopls', -- if set to 'gopls' will use golsp format
gofmt = 'gopls', -- if set to gopls will use golsp format
max_line_line = 120,
tag_transform = false,
test_dir = '',
comment_placeholder = ' ',
lsp_cfg = true, -- false: use your own lspconfig
lsp_gofumpt = true, -- true: set default gofmt in gopls format to gofumpt
lsp_on_attach = true, -- use on_attach from go.nvim
dap_debug = true,
})
local protocol = require'vim.lsp.protocol'
EOF
2021-03-10 13:21:01 +00:00
```
2021-07-12 04:25:07 +00:00
This will setup gopls with non default configure provided by go.nvim (Includes lspconfig default keymaps)