lua | ||
LICENSE | ||
README.md | ||
TODO.md |
go.nvim
A modern golang neovim plugin based on treesitter and nvim-lsp. It is written in Lua and async as much as possible. PR & Suggestions welcome. The plugin covers most features required for a gopher.
- Async jobs
- Syntex highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support treesitter, try aurora. Also, there are quite a few listed in awesome-neovim
- 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 gopls setup lspconfig.lua
- Runtime lint/vet/compile: Supported by lsp (once you setup up your lsp client), GoLint with golangci-lint also supported
- Build/Make/Test: Go.nvim provides supports for these by an async job wrapper.
- Unit test: Support 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...
install
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.
autocmd BufWritePre *.go :silent! lua require('go.format').gofmt()
To startup/setup the plugin
require('go').setup()
Screenshots
Add comments
Add/Remove tags
refactor gorename
gorename as an alternative to gopls rename as it supports rename across packages
code format
nvim-lsp support goimport by default.
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
require("go.format").gofmt()
require("go.format").goimport()
Auto fill struct
Note: auto fill struct also supported by gopls lsp-action
Textobject
Supported by treesitter. TS provided better parse result compared to regular expression. Check my treesitter config file on how to setup textobjects. Also with treesitter-objects, you can move, swap the selected blocks of codes, which is fast and accurate.
Build and test
Provided wrapper for gobulild/test etc with async make Also suggest to use vim-test, which can run running tests on different granularities.
Unit test with gotests and testify
Support table based unit test auto generate, parse current function/method name using treesitter
Modifytags
Modify struct tags by gomodifytags
and treesitter
GoFmt
nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumports (stricter version of goimport)
Comments and Doc
Auto doc (to suppress golang-lint warning), generate comments by treesitter parsing result
type GoLintComplaining struct{}
And run
lua.require('go.comment').gen() -- or your faviourite key binding and setup placeholder "no more complaint ;P"
The code will be:
// GoLintComplaining struct no more complaint ;P
type GoLintComplaining struct{}
LSP
LSP supported by nvim-lsp is good enough for a gopher. If you looking for a better GUI. You can install navigator, or lspsaga, and lsp-utils etc.
Lint
Supported by LSP, also GoLint command (by calling golangcl-lint) if you need background golangci-lint check, you can configure it with ALE
configuration
Configure from lua suggested:
require('go').setup(cfg = {
goimport='gofumports', -- g:go_nvim_goimport
gofmt = 'gofumpt', --g:go_nvim_gofmt,
max_len = 120, -- g:go_nvim_max_len
transform = false, -- vim.g.go_nvim_tag_transfer check gomodifytags for details
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
comment_placeholder = '' , -- vim.g.go_nvim_comment_placeholder your cool placeholder e.g. ﳑ
verbose = false, -- output loginf in messages
})
You will need to add keybind yourself: e.g
vim.cmd("autocmd FileType go nmap <Leader><Leader>l GoLint")
vim.cmd("autocmd FileType go nmap <Leader>gc :lua require('go.comment').gen()")
Nvim LSP setup
For golang, the default gopls setup works perfectly fine, or you can install navigator.lua which can auto setup all lsp clients.
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, folke/lsp-trouble.nvim. Nvim-tree and Bufferline also introduced lsp diagnostic hooks.
Also, you can do this: put all diag error/warning of your project in quickfix.
-- hdlr alternatively, use lua vim.lsp.diagnostic.set_loclist({open_loclist = false})
-- true to open loclist
local diag_hdlr = function(err, method, result, client_id, bufnr, config)
-- vim.lsp.diagnostic.clear(vim.fn.bufnr(), client.id, nil, nil)
vim.lsp.diagnostic.on_publish_diagnostics(err, method, result, client_id, bufnr, config)
if result and result.diagnostics then
local item_list = {}
local s = result.uri
local fname = s
for _, v in ipairs(result.diagnostics) do
i, j = string.find(s, "file://")
if j then
fname = string.sub(s, j + 1)
end
table.insert(item_list, { filename = fname, lnum = v.range.start.line + 1, col = v.range.start.character + 1; text = v.message; })
end
local old_items = vim.fn.getqflist()
for _, old_item in ipairs(old_items) do
local bufnr = vim.uri_to_bufnr(result.uri)
if vim.uri_from_bufnr(old_item.bufnr) ~= result.uri then
table.insert(item_list, old_item)
end
end
vim.fn.setqflist({}, ' ', { title = 'LSP'; items = item_list; })
end
end
vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(
diag_hdlr,
{
-- Enable underline, use default values
underline = true,
-- Enable virtual text, override spacing to 0
virtual_text = {
spacing = 0,
prefix = '', --'',
},
-- Use a function to dynamically turn signs off
-- and on, using buffer local variables
signs = true,
-- Disable a feature
update_in_insert = false,
}
)