From b9f161c18efd948becbbd7cfb37e4677cf2f31b9 Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 17 Feb 2023 21:54:44 +1100 Subject: [PATCH] null-ls source: golangci-lint and gotest is async now gomvp minor fix command auto complete --- README.md | 9 ++-- lua/go/commands.lua | 116 ++++++++++++++++++++++++++++++++++++-------- lua/go/gomvp.lua | 4 +- lua/go/null_ls.lua | 81 ++++++++++++++++++++++++++++--- lua/go/utils.lua | 2 +- 5 files changed, 179 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 394264b..68c79b6 100644 --- a/README.md +++ b/README.md @@ -976,14 +976,16 @@ end ``` ## Integrate null-ls -### The plugin provides `gotest` LSP diagnostic source for null-ls +### The plugin provides: +* `gotest` LSP diagnostic source for null-ls +* `golangci_lint` A async version of golangci-lint null-ls lint +* `gotest_action` LSP test code action for null-ls Gotest allow you run `go test ` when you save your go file and add diagnostics to nvim ```lua local null_ls = require("null-ls") local sources = { - null_ls.builtins.diagnostics.golangci_lint, null_ls.builtins.diagnostics.revive, null_ls.builtins.formatting.golines.with({ extra_args = { @@ -995,7 +997,8 @@ local sources = { -- for go.nvim local gotest = require("go.null_ls").gotest() local gotest_codeaction = require("go.null_ls").gotest_action() -table.insert(sources, gotest) +local golangci_lint = require("go.null_ls").golangci_lint() +table.insert(sources, gotest, golangci_lint) table.insert(sources, gotest_codeaction) null_ls.setup({ sources = sources, debounce = 1000, default_timeout = 5000 }) diff --git a/lua/go/commands.lua b/lua/go/commands.lua index 2165b0e..6af2e0f 100644 --- a/lua/go/commands.lua +++ b/lua/go/commands.lua @@ -60,7 +60,12 @@ local dap_config = function() return end gdap.run(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.dbg_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.dbg_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoCreateLaunch', function(_) require('go.launch').config() end) @@ -132,28 +137,36 @@ return { create_cmd('GoImport', function(opts) require('go.format').goimport(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.doc_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.doc_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoGet', function(opts) require('go.goget').run(opts.fargs) end, { nargs = '*' }) local gobin = _GO_NVIM_CFG.go - local cmd = string.format([[command! -nargs=* GoGenerate :setl makeprg=%s\ generate | lua require'go.asyncmake'.make()]], gobin) + local cmd = string.format( + [[command! -nargs=* GoGenerate :setl makeprg=%s\ generate | lua require'go.asyncmake'.make()]], + gobin + ) vim.cmd(cmd) - + cmd = string.format( [[command! -nargs=* -complete=customlist,v:lua.package.loaded.go.package_complete GoBuild :setl makeprg=%s\ build | lua require'go.asyncmake'.make()]], gobin ) vim.cmd(cmd) - + cmd = string.format( [[command! -nargs=* -complete=customlist,v:lua.package.loaded.go.package_complete GoVet :setl makeprg=%s\ vet | lua require'go.asyncmake'.make()]], gobin ) vim.cmd(cmd) - + cmd = string.format( [[command! -nargs=* -complete=customlist,v:lua.package.loaded.go.package_complete GoRun :setl makeprg=%s\ run | lua require'go.asyncmake'.make()]], gobin @@ -171,22 +184,42 @@ return { create_cmd('GoTest', function(opts) require('go.gotest').test(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoTestSum', function(opts) if opts.fargs[1] == '-w' then return require('go.gotestsum').watch() end require('go.gotestsum').run(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoCoverage', function(opts) require('go.coverage').run(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoPkgOutline', function(opts) require('go.package').outline(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) -- vim.cmd([[command! GoTestCompile :setl makeprg=go\ build | :GoMake]]) --print-issued-lines=false @@ -214,10 +247,20 @@ return { create_cmd('GoTestFile', function(opts) require('go.gotest').test_file(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoTestPkg', function(opts) require('go.gotest').test_package(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.package_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoAddTest', function(opts) require('go.gotests').fun_test(unpack(opts.fargs)) end) @@ -250,28 +293,58 @@ return { create_cmd('GoModifyTag', function(opts) require('go.tags').modify(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.modify_tags_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.modify_tags_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoAddTag', function(opts) require('go.tags').add(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.add_tags_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.add_tags_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoRmTag', function(opts) require('go.tags').rm(unpack(opts.fargs)) end, { nargs = '*' }) create_cmd('GoImpl', function(opts) require('go.impl').run(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.impl_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.impl_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoDoc', function(opts) require('go.godoc').run(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.doc_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.doc_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoInstallBinary', function(opts) require('go.install').install(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.tools_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.tools_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoUpdateBinary', function(opts) require('go.install').update(unpack(opts.fargs)) - end, { complete = function(a, l) return package.loaded.go.tools_complete(a, l) end, nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.tools_complete(a, l) + end, + nargs = '*', + }) create_cmd('GoInstallBinaries', function(_) require('go.install').install_all() @@ -361,7 +434,12 @@ return { create_cmd('Gomvp', function(opts) require('go.gomvp').run(opts.fargs) - end, { nargs = '*' }) + end, { + complete = function(a, l) + return package.loaded.go.package_complete(a, l) + end, + nargs = '*', + }) create_cmd('Govulnckeck', function(opts) require('go.govulncheck').run(opts.fargs) diff --git a/lua/go/gomvp.lua b/lua/go/gomvp.lua index c463969..6605a8f 100644 --- a/lua/go/gomvp.lua +++ b/lua/go/gomvp.lua @@ -29,8 +29,8 @@ function M.run(args) new_module = input({ prompt = "new module name: ", default = old_mod, - on_confirm = function(input) - new_module = input + on_confirm = function(inp) + new_module = inp end}) end vim.list_extend(cmd, { old_mod, new_module }) diff --git a/lua/go/null_ls.lua b/lua/go/null_ls.lua index ca2ed98..75bd8f1 100644 --- a/lua/go/null_ls.lua +++ b/lua/go/null_ls.lua @@ -2,6 +2,7 @@ local vim, fn = vim, vim.fn local utils = require('go.utils') local log = utils.log +local null_ls = require('null-ls') local extract_filepath = utils.extract_filepath local function handler() @@ -110,9 +111,76 @@ local function handler() return done(diags) end end +local h = require('null-ls.helpers') +local methods = require('null-ls.methods') + +local DIAGNOSTICS_ON_SAVE = methods.internal.DIAGNOSTICS_ON_SAVE + -- register with -- null_ls.register(gotest) return { + golangci_lint = function() + local golangci_diags = {} + + return { + name = 'golangci_lint', + meta = { + url = 'https://golangci-lint.run/', + description = 'A Go linter aggregator.', + }, + method = DIAGNOSTICS_ON_SAVE, + filetypes = { 'go' }, + generator_opts = { + command = 'golangci-lint', + to_stdin = true, + from_stderr = false, + ignore_stderr = true, + async = true, + fn = function() + return function(arg, done) + log(arg) + return done(golangci_diags) + end + end, + args = function() + golangci_diags = {} -- CHECK: is here the best place to call + return { + 'run', + '--fix=false', + '--out-format=json', + '--path-prefix', + '$ROOT', + } + end, + format = 'json', + check_exit_code = function(code) + return code <= 2 + end, + on_output = function(params) + if params.output['Report'] and params.output['Report']['Error'] then + log:warn(params.output['Report']['Error']) + return golangci_diags + end + local issues = params.output['Issues'] + if type(issues) == 'table' then + for _, d in ipairs(issues) do + if d.Pos.Filename == params.bufname then + table.insert(golangci_diags, { + source = string.format('golangci-lint:%s', d.FromLinter), + row = d.Pos.Line, + col = d.Pos.Column, + message = d.Text, + severity = h.diagnostics.severities['warning'], + }) + end + end + end + return golangci_diags + end, + }, + factory = h.generator_factory, + } + end, gotest = function() local nulls = utils.load_plugin('null-ls', 'null-ls') if nulls == nil then @@ -120,20 +188,18 @@ return { return end - local null_ls = require('null-ls') - local methods = require('null-ls.methods') - return { name = 'gotest', method = null_ls.methods.DIAGNOSTICS_ON_SAVE, filetypes = { 'go' }, generator = null_ls.generator({ command = 'go', + async = true, args = function() local gt = require('go.gotest') local a = { 'test', '-json' } local tests = gt.get_test_cases() - log(tests) + -- log(tests) local pkg = require('go.gotest').get_test_path() if not tests or not tests[1] then @@ -146,14 +212,14 @@ return { table.insert(a, tests) table.insert(a, pkg) end - log(a) + -- log(a) return a end, to_stdin = false, method = methods.internal.DIAGNOSTICS_ON_SAVE, from_stderr = false, format = 'raw', - timeout = 10000, + timeout = 5000, check_exit_code = function(code, stderr) local success = code <= 1 log(code, stderr) @@ -161,9 +227,8 @@ return { -- can be noisy for things that run often (e.g. diagnostics), but can -- be useful for things that run on demand (e.g. formatting) vim.schedule_wrap(function() - vim.notify('go test failed: ' .. tostring(stderr), vim.log.levels.WARN) + vim.notify('go test failed: ' .. tostring(stderr), vim.log.levels.WARN) end) - end return true end, diff --git a/lua/go/utils.lua b/lua/go/utils.lua index e331dc4..dba0ca1 100644 --- a/lua/go/utils.lua +++ b/lua/go/utils.lua @@ -819,7 +819,7 @@ util.extract_filepath = function(msg) end pos2 = msg:find(':') local fname = msg:sub(pos, pos2 - 1) - util.log(fname) + util.log(fname, namepath[fname]) if namepath[fname] ~= nil then return namepath[fname] end