diff --git a/lua/myworkflow/autocommands.lua b/lua/myworkflow/autocommands.lua index fbca73b..91015ec 100644 --- a/lua/myworkflow/autocommands.lua +++ b/lua/myworkflow/autocommands.lua @@ -1,5 +1,21 @@ +local group = vim.api.nvim_create_augroup("autoformat", {}) vim.api.nvim_create_autocmd('BufWritePre', { + group = group, callback = function() vim.lsp.buf.format { async = false } end }) + +local gotests = require("myworkflow.go-tests") +local atgroup = vim.api.nvim_create_augroup("autotest", {}) + +vim.api.nvim_create_autocmd('BufWritePost', + { + group = atgroup, + pattern = { "*.go" }, + callback = function() + gotests.goRunTests() + gotests.goSetMarks() + end + } +) diff --git a/lua/myworkflow/go-tests.lua b/lua/myworkflow/go-tests.lua new file mode 100644 index 0000000..84de63a --- /dev/null +++ b/lua/myworkflow/go-tests.lua @@ -0,0 +1,136 @@ +local M = { + results = {} +} + +local ns = vim.api.nvim_create_namespace("live-tests") + +local test_function_query_string = [[ +( + (function_declaration + name: (identifier) @name + parameters: + (parameter_list + (parameter_declaration + name: (identifier) + type: (pointer_type + (qualified_type + package: (package_identifier) @_package_name + name: (type_identifier) @_type_name))))) + + (#eq? @_package_name "testing") + (#eq? @_type_name "T") + (#eq? @name "%s") +) +]] + +local find_test_line = function(go_bufnr, name) + local formatted = string.format(test_function_query_string, name) + local query = vim.treesitter.query.parse("go", formatted) + local parser = vim.treesitter.get_parser(go_bufnr, "go", {}) + local tree = parser:parse()[1] + local root = tree:root() + + for id, node in query:iter_captures(root, go_bufnr, 0, -1) do + if id == 1 then + local range = { node:range() } + return range[1] + end + end +end + +local function clear(table) + for k in pairs(table) do + table[k] = nil + end +end + +vim.api.nvim_create_user_command('GoTest', function() + M.goRunTests() +end, {}) + +vim.api.nvim_create_user_command('GoPrintResults', function() + M.goPrintResults() +end, {}) + +vim.api.nvim_create_user_command('GoSetTestMarks', function() + M.goSetMarks() +end, {}) + +vim.api.nvim_create_user_command('GoClearResults', function() + clear(M.results) +end, {}) + + +vim.api.nvim_create_user_command('GoClearTestMarks', function() + local currbuf = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_clear_namespace(currbuf, ns, 0, -1) +end, {}) + +function M.goRunTests() + -- TODO: replace jobstart/jobwait with system() + local id = vim.fn.jobstart({ "go", "test", "./...", "-json" }, { + stdout_buffered = true, + on_stdout = function(_, data) + if not data then + return + end + + clear(M.results) + + for _, line in ipairs(data) do + if line == "" then goto continue end + local decoded = vim.json.decode(line) + + if decoded.Test == nil then + goto continue + end + if decoded.Action == 'pass' or decoded.Action == 'fail' then + M.results[decoded.Test] = { Action = decoded.Action } + end + + ::continue:: + end + end, + on_exit = function() + end + }) + vim.fn.jobwait({ id }) +end + +function M.goPrintResults() + print(vim.inspect(M.results)) +end + +function M.goSetMarks() + local currbuf = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_clear_namespace(currbuf, ns, 0, -1) + local text = {} + local failed = {} + + for test, val in pairs(M.results) do + local linenum = find_test_line(currbuf, test) + if linenum == nil then goto continue end + + if val.Action == 'pass' then + text = { "✓" } + vim.api.nvim_buf_set_extmark(currbuf, ns, linenum, 0, { + virt_text = { text }, + }) + elseif val.Action == 'fail' then + table.insert(failed, { + bufnr = currbuf, + lnum = linenum, + col = 0, + severity = vim.diagnostic.severity.ERROR, + source = "go-test", + message = "Test Failed", + user_data = {}, + }) + end + + ::continue:: + end + vim.diagnostic.set(ns, currbuf, failed, {}) +end + +return M diff --git a/lua/myworkflow/init.lua b/lua/myworkflow/init.lua index 68169b0..bbac49f 100644 --- a/lua/myworkflow/init.lua +++ b/lua/myworkflow/init.lua @@ -2,3 +2,4 @@ require("myworkflow.remap") require("myworkflow.set") require("myworkflow.packer") require("myworkflow.autocommands") +require("myworkflow.go-tests") diff --git a/lua/myworkflow/packer.lua b/lua/myworkflow/packer.lua index ec0763e..a5e36a2 100644 --- a/lua/myworkflow/packer.lua +++ b/lua/myworkflow/packer.lua @@ -30,6 +30,7 @@ return require('packer').startup(function(use) use 'mfussenegger/nvim-dap' use 'leoluz/nvim-dap-go' use 'rcarriga/nvim-dap-ui' + use 'jbyuki/one-small-step-for-vimkind' -- Autocompletion use 'hrsh7th/cmp-nvim-lsp'