diff --git a/README.md b/README.md index 0d8b422ae..c11a31b8a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # 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. PR & Suggestions are welcome. +A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. Written in Lua and designed to be as asynchronous as possible, the repo welcomes PR & Suggestions are welcome. The plugin covers most features required for a gopher. @@ -13,6 +12,7 @@ The plugin covers most features required for a gopher. - 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) +- Better `go doc` with GoPkgOutline - gopls commands: e.g. fillstruct, organize imports, list modules, list packages, gc_details, generate, change signature, etc. - Runtime lint/vet/compile: Supported by LSP (once you set up your LSP client), GoLint with golangci-lint also supported @@ -49,7 +49,8 @@ The plugin covers most features required for a gopher. Use your favorite package manager to install. The dependency `treesitter` (and optionally, treesitter-objects) should be installed the first time you use it. Also Run `TSInstall go` to install the go parser if not installed yet. `sed` is recommended to run this plugin. - +
+ plug ### [vim-plug](https://github.com/junegunn/vim-plug) ```vim @@ -58,7 +59,10 @@ Plug 'neovim/nvim-lspconfig' Plug 'ray-x/go.nvim' Plug 'ray-x/guihua.lua' ; recommended if need floating window support ``` +
+
+ Packer ### [packer.nvim](https://github.com/wbthomason/packer.nvim) ```lua @@ -67,7 +71,10 @@ use 'ray-x/guihua.lua' -- recommended if need floating window support use 'neovim/nvim-lspconfig' use 'nvim-treesitter/nvim-treesitter' ``` +
+
+ Lazy ### [lazy.nvim](https://github.com/folke/lazy.nvim) ```lua @@ -86,6 +93,7 @@ use 'nvim-treesitter/nvim-treesitter' 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 image @@ -746,6 +754,8 @@ some of them are not exposed to user, but you can still use it in your lua setup ## configuration Configure from lua suggested, The default setup: +
+ Default setup ```lua require('go').setup({ @@ -766,7 +776,9 @@ require('go').setup({ comment_placeholder = '' , -- comment_placeholder your cool placeholder e.g. 󰟓     icons = {breakpoint = '🧘', currentpos = '🏃'}, -- setup to `false` to disable icons setup verbose = false, -- output loginf in messages - lsp_semantic_highlights = true, -- use highlights from gopls + lsp_semantic_highlights = true, -- use highlights from gopls; false: use treesitter semantic highlights + lsp_semantic_highlights_priority = nil, -- set priority < 100 to use treesitter semantic highlights; set to > 100 to + -- use gopls; nil: use default priority (125 for nvim 0.10) lsp_cfg = false, -- true: use non-default gopls setup specified in go/lsp.lua -- false: do nothing -- if lsp_cfg is a table, merge table with with non-default gopls setup in go/lsp.lua, e.g. @@ -876,8 +888,22 @@ require('go').setup({ on_stderr = function(err, data) _, _ = err, data end, -- callback for stderr on_exit = function(code, signal, output) _, _, _ = code, signal, output end, -- callback for jobexit, output : string iferr_vertical_shift = 4 -- defines where the cursor will end up vertically from the begining of if err statement + comment = { + placeholder = '' , -- comment_placeholder your cool placeholder e.g. 󰟓     + highlight = true, -- set to false to disable comment highlight + queries = nil -- set to a table of queries to use for comment highlight see comment.lua + highlight_groups = { -- default comment highlight groups, see comment.lua + -- redefine or set back to Comment to disable + -- types = 'GoCommentType', + -- functions = 'GoCommentFunction', + -- variables = 'GoCommentVariable', + -- constants = 'GoCommentConstant', + -- parameters = 'GoCommentParameter', + } + } }) ``` +
You will need to add keybind yourself: e.g @@ -909,6 +935,9 @@ This will override your global `go.nvim` setup I did not provide textobject support in the plugin. Please use treesitter textobject plugin. My treesitter config: +
+ textobject setup with treesitter + ```lua require "nvim-treesitter.configs".setup { incremental_selection = { diff --git a/doc/go.txt b/doc/go.txt index d4c794d24..e0182c3f0 100644 --- a/doc/go.txt +++ b/doc/go.txt @@ -380,7 +380,6 @@ You can setup go.nvim with following options: max_line_len = 120, tag_transform = false, test_dir = "", - comment_placeholder = "  ", icons = { breakpoint = "🧘", currentpos = "🏃" }, -- set to false to disable -- this option verbose = false, @@ -458,6 +457,12 @@ You can setup go.nvim with following options: run_in_floaterm = false, -- set to true to run in float window. luasnip = false, -- set true to enable included luasnip iferr_vertical_shift = 4 -- defines where the cursor will end up vertically from the begining of if err statement after GoIfErr command + comment = { + placeholder = '  ', + highlight = true, -- set to false to disable + queries = nil, -- set to a table of queries to use for comment highlight see comment.lua + highlight_groups = nil + } } vim:tw=78:ts=8:sts=8:sw=8:ft=help:norl:expandtab diff --git a/lua/go.lua b/lua/go.lua index d2447a65a..e1b04d2b7 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -18,7 +18,6 @@ _GO_NVIM_CFG = { gotests_template_dir = '', -- sets gotests -template_dir parameter (check gotests for details) gotest_case_exact_match = true, -- default to true, if set to false will match any part of the test name - comment_placeholder = '  ', icons = { breakpoint = '🧘', currentpos = '🏃' }, -- set to false to disable icons setup sign_priority = 7, -- set priority of signs used by go.nevim verbose = false, @@ -27,7 +26,9 @@ _GO_NVIM_CFG = { -- true: apply non-default gopls setup defined in go/gopls.lua -- if lsp_cfg is a table, merge table with with non-default gopls setup in go/gopls.lua, e.g. lsp_gofumpt = false, -- true: set default gofmt in gopls format to gofumpt - lsp_semantic_highlights = true, -- use highlights from gopls + lsp_semantic_highlights = true, -- use highlights from gopls, false: use treesitter highlights + lsp_semantic_highlights_priority = nil, -- set priority of semantic highlights to < 100 to use treesitter highlights; + -- > 100 to use gopls semantics token lsp_on_attach = nil, -- nil: use on_attach function defined in go/lsp.lua for gopls, -- when lsp_cfg is true -- if lsp_on_attach is a function: use this function as on_attach function for gopls, @@ -83,9 +84,11 @@ _GO_NVIM_CFG = { -- so you will run `watchexe --restart -v -e go go run ` end, }, - -- deprecated setups for nvim version < 0.10 lsp_inlay_hints = { enable = true, + + -- deprecated setups for nvim version < 0.10 + style = 'inlay', -- 'default: inlay', 'eol': show at end of line, 'inlay': show in the middle of the line -- Note: following setup only for for style == 'eol' @@ -177,6 +180,13 @@ _GO_NVIM_CFG = { _, _, _ = code, signal, output end, -- callback for jobexit, output : string iferr_vertical_shift = 4, -- defines where the cursor will end up vertically from the begining of if err statement after GoIfErr command + comment = { + placeholder = '  ', + highlight = false, -- set to true to disable + queries = nil, -- set to a table of queries to use for comment highlight see comment.lua + highlight_groups = nil, + highlight_debounce = 1000, -- 1000ms + }, } -- TODO: nvim_{add,del}_user_command https://github.com/neovim/neovim/pull/16752 @@ -218,18 +228,16 @@ function go.setup(cfg) vim.log.levels.WARN ) 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.comment_placeholder ~= nil then vim.notify( - 'go.nvim lsp_diag_virtual_text deprecated, use diagnostic.virtual_text', + 'go.nvim comment_placeholder deprecated, use comment.placeholder', vim.log.levels.WARN ) + cfg.comment.placeholder = cfg.comment_placeholder end - if cfg.lsp_diag_signs ~= nil then - vim.notify('go.nvim lsp_diag_signs deprecated, use diagnostic.signs', vim.log.levels.WARN) + if cfg.goimport ~= nil then + vim.notify('go.nvim goimport deprecated, use goimports', vim.log.levels.WARN) + cfg.goimports = cfg.goimport end if cfg.disable_defaults then reset_tbl(_GO_NVIM_CFG) @@ -242,6 +250,10 @@ function go.setup(cfg) vim.notify('go.nvim go binary is not setup', vim.log.levels.ERROR) end + if _GO_NVIM_CFG.lsp_semantic_highlights_priority then + vim.highlight.priorities.semantic_tokens = _GO_NVIM_CFG.lsp_semantic_highlights_priority + end + if _GO_NVIM_CFG.max_line_len > 0 and _GO_NVIM_CFG.gofmt ~= 'golines' then vim.notify('go.nvim max_line_len only effective when gofmt is golines', vim.log.levels.WARN) end @@ -250,6 +262,7 @@ function go.setup(cfg) vim.defer_fn(function() require('go.project').load_project() require('go.utils').set_nulls() + require('go.comment') end, 1) if _GO_NVIM_CFG.run_in_floaterm then diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 831e87828..2a423e13c 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -1,49 +1,50 @@ -- todo -- for func name(args) rets {} -- add cmts // name : rets -local comment = {} -local placeholder = _GO_NVIM_CFG.comment_placeholder or "" -local ulog = require("go.utils").log -local api = vim.api +local comment = { hl_timestamp = {} } +local placeholder = _GO_NVIM_CFG.comment.placeholder or '' +local ulog = require('go.utils').log +local api = vim.api +local node_from_match = require('go.ts.utils').node_from_match + local gen_comment = function() local comments = nil - local ns = require("go.ts.go").get_package_node_at_pos() - if ns ~= nil and ns ~= {} then + local ns = require('go.ts.go').get_package_node_at_pos() + if ns then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// Package " .. ns.name .. " provides " .. ns.name + comments = '// Package ' .. ns.name .. ' provides ' .. ns.name return comments, ns end - ns = require("go.ts.go").get_func_method_node_at_pos() - if ns ~= nil and ns ~= {} then - -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + ns = require('go.ts.go').get_func_method_node_at_pos() + if ns then + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_struct_node_at_pos() - if ns ~= nil and ns ~= {} then - comments = "// " .. ns.name .. " " .. ns.type + ns = require('go.ts.go').get_struct_node_at_pos() + if ns then + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_interface_node_at_pos() - if ns ~= nil and ns ~= {} then + ns = require('go.ts.go').get_interface_node_at_pos() + if ns then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_type_node_at_pos() - if ns ~= nil and ns ~= {} then + ns = require('go.ts.go').get_type_node_at_pos() + if ns then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - return "" + return '' end local wrap_comment = function(comment_line, ns) - if string.len(comment_line) > 0 and placeholder ~= nil and string.len(placeholder) > 0 then - return comment_line .. " " .. placeholder, ns + if string.len(comment_line) > 0 and string.len(placeholder) > 0 then + return comment_line .. ' ' .. placeholder, ns end return comment_line, ns end @@ -55,14 +56,14 @@ comment.gen = function() local bufnr = api.nvim_get_current_buf() if ns == nil then -- nothing found - local ts_utils = require("nvim-treesitter.ts_utils") + local ts_utils = require('nvim-treesitter.ts_utils') ns = ts_utils.get_node_at_cursor() - local node_text = require("go.utils").get_node_text(ns, bufnr) + local node_text = vim.treesitter.get_node_text(ns, bufnr) local line = api.nvim_get_current_line() - local regex = "^(%s+)" + local regex = '^(%s+)' local q = line:match(regex) - c = (q or "") .. "// " .. node_text + c = (q or '') .. '// ' .. node_text c, _ = wrap_comment(c, {}) vim.fn.append(row - 1, c) vim.fn.cursor(row, #c + 1) @@ -70,15 +71,309 @@ comment.gen = function() end ulog(vim.inspect(ns)) row, col = ns.dim.s.r, ns.dim.s.c - ulog("set cursor " .. tostring(row)) + ulog('set cursor ' .. tostring(row)) api.nvim_win_set_cursor(0, { row, col }) -- insert doc vim.fn.append(row - 1, c) -- set curosr vim.fn.cursor(row, #c + 1) -- enter into insert mode - api.nvim_command("startinsert!") + api.nvim_command('startinsert!') return c end +local ns_id = vim.api.nvim_create_namespace('GoCommentCode') + +local function highlight_go_code_in_comments() + local bufnr = vim.api.nvim_get_current_buf() + local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype') + if ft ~= 'go' or not _GO_NVIM_CFG.comment.highlight then + return + end + + -- Create a namespace for the highlights + -- Clear any existing highlights in this namespace + vim.api.nvim_buf_clear_namespace(bufnr, ns_id, 0, -1) + + -- Get the Tree-sitter parser for Go + local parser = vim.treesitter.get_parser(bufnr, 'go') + local tree = parser:parse()[1] + local root = tree:root() + + -- Collect code elements (types, functions, variables, constants, keywords, parameters) + local code_elements = { + types = {}, + functions = {}, + variables = {}, + constants = {}, + parameters = {}, + methods = {}, + methods_params = {}, + keywords = {}, + } + + -- Define queries to capture code elements + local queries = { + types = [[ + (type_spec name: (type_identifier) @type_name) + ]], + functions = [[ + (function_declaration name: (identifier) @function_name) + ]], + variables = [[ + (var_spec name: (identifier) @variable_name) + ]], + constants = [[ + (const_spec name: (identifier) @constant_name) + ]], + parameters = [[ + (function_declaration + parameters: (parameter_list + (parameter_declaration + name: (identifier) @param_name))) + ]], + methods = [[ + (method_declaration + name: (field_identifier) @method_name) + ]], + methods_params = [[ + (method_declaration + parameters: (parameter_list + (parameter_declaration + name: (identifier) @param_name))) + ]], + -- Keywords are predefined in Go + keywords = { + 'func', + 'interface', + 'defer', + 'map', + 'struct', + 'chan', + 'package', + 'const', + 'returns', + '+build', + 'go:build', + 'go:generate', + 'Deprecated', + }, + } + + if _GO_NVIM_CFG.comment.queries then + for k, v in pairs(_GO_NVIM_CFG.comment.queries) do + queries[k] = v + end + end + + -- Function to collect names from query + local function collect_names(query_string, capture_name, target_table) + local query = vim.treesitter.query.parse('go', query_string) + local capture_index = nil + + -- Find the index of the capture name in the query's captures + for idx, name in ipairs(query.captures) do + if name == capture_name then + capture_index = idx + break + end + end + + if not capture_index then + vim.notify('Capture name "' .. capture_name .. '" not found in query', vim.log.levels.INFO) + return + end + + -- Note capture_index should be 1 + for pattern, match, metadata in query:iter_matches(root, bufnr, 0, -1) do + local node = node_from_match(match, capture_index) + local name = vim.treesitter.get_node_text(node, bufnr) + target_table[name] = true + ulog('name', name) + end + end + + -- Collect code elements + collect_names(queries.types, 'type_name', code_elements.types) + collect_names(queries.functions, 'function_name', code_elements.functions) + collect_names(queries.methods, 'method_name', code_elements.methods) + collect_names(queries.methods_params, 'param_name', code_elements.methods_params) + collect_names(queries.variables, 'variable_name', code_elements.variables) + collect_names(queries.constants, 'constant_name', code_elements.constants) + collect_names(queries.parameters, 'param_name', code_elements.parameters) + + -- Build patterns for each category + local function build_pattern(names) + local words = {} + for name, _ in pairs(names) do + table.insert(words, vim.fn.escape(name, '\\')) + end + if #words == 0 then + return nil + end + return '\\C\\<\\(' .. table.concat(words, '\\|') .. '\\)\\>' + end + + local patterns = { + types = build_pattern(code_elements.types), + functions = build_pattern(code_elements.functions), + methods = build_pattern(code_elements.methods), + variables = build_pattern(code_elements.variables), + constants = build_pattern(code_elements.constants), + parameters = build_pattern(code_elements.parameters), + methods_params = build_pattern(code_elements.methods_params), + keywords = '\\<\\(' .. table.concat(queries.keywords, '\\|') .. '\\)\\>', + -- match square brackets and content inside them e.g. [slice.Sort] + -- matchbrackets = '\\[\\([^\\[\\]]*\\)\\]', + } + + -- Compile regexes + local regexes = {} + for category, pattern_str in pairs(patterns) do + if pattern_str then + regexes[category] = vim.regex(pattern_str) + end + end + + -- Define the highlight groups for each category + local highlight_groups = { + types = '@comment.go.type', + functions = '@comment.go.function', + methods = '@comment.go.method', + variables = '@comment.go.var', + constants = '@comment.go.constant', + parameters = '@comment.go.para', + methods_params = '@comment.go.para', + keywords = '@comment.go.keyword', + matchbrackets = '@comment.go.method', + } + + if _GO_NVIM_CFG.comment.highlight_groups then + for k, v in pairs(_GO_NVIM_CFG.comment.highlight_groups) do + highlight_groups[k] = v + end + end + + -- Define a query to find comment nodes + local comment_query = vim.treesitter.query.parse('go', '(comment) @comment') + + local capture_index = nil + + -- Find the index of the capture name in the query's captures + for idx, name in ipairs(comment_query.captures) do + ulog('name', name) + if name == 'comment' then + capture_index = idx + break + end + end + + -- Iterate over the captures in the query + for _, matches, _ in comment_query:iter_matches(root, bufnr, 0, -1) do + local node = node_from_match(matches, capture_index) + local start_row, start_col, end_row, end_col = node:range() + + for row = start_row, end_row do + local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] + local col_start = 0 + local col_end = #line + + if row == start_row then + col_start = start_col + end + if row == end_row then + col_end = end_col + end + + -- For each category, search for matches and apply highlights + for category, regex in pairs(regexes) do + local s = col_start + while s < col_end do + local m_start, m_end = regex:match_line(bufnr, row, s, col_end) + if not m_start then + break + end + + -- m_start and m_end are relative to 's' + local hl_start_col = m_start + s + local hl_end_col = m_end + s + -- ulog('highlight', row, hl_start_col, hl_end_col, line:sub(hl_start_col, hl_end_col)) + + -- Apply the highlight to the matched word + vim.api.nvim_buf_add_highlight( + bufnr, + ns_id, + highlight_groups[category], + row, + hl_start_col, + hl_end_col + ) + + s = hl_end_col -- Move to the end of the current match + end + end + end + end +end + +---@diagnostic disable-next-line: unused-local +local function toggle_go_comment_highlight() + _GO_NVIM_CFG.comment.highlight = not _GO_NVIM_CFG.comment.highlight + if _GO_NVIM_CFG.comment.highlight then + highlight = require('go.utils').throttle( + highlight_go_code_in_comments, + _GO_NVIM_CFG.comment.highlight_debounce + ) + highlight() + else + vim.api.nvim_buf_clear_namespace(0, ns_id, 0, -1) + end +end + +comment.highlight = highlight_go_code_in_comments +comment.toggle_highlight = toggle_go_comment_highlight + +vim.api.nvim_create_user_command('ToggleGoCommentHighlight', function() + require('go.comment').toggle_highlight() +end, {}) + +local group = vim.api.nvim_create_augroup('gonvim__comment_hl', {}) +vim.api.nvim_create_autocmd( + { 'BufEnter', 'BufWritePost', 'WinEnter', 'InsertLeave', 'CursorHold' }, + { + pattern = { '*.go' }, + group = group, + callback = function(opts) + if _GO_NVIM_CFG.comment.highlight then + -- check + local filename = vim.api.nvim_buf_get_name(0) + local timestamp = comment.hl_timestamp[filename] + if timestamp and timestamp == vim.fn.getftime(filename) then + return + end + require('go.comment').highlight() + comment.hl_timestamp[filename] = vim.fn.getftime(filename) + end + end, + } +) + +-- Define highlight groups for code elements within comments +vim.api.nvim_set_hl(0, '@comment.go.type', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, '@comment.go.function', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, '@comment.go.method', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, '@comment.go.var', { link = '@markup.emphasis' }) +vim.api.nvim_set_hl(0, '@comment.go.constant', { link = '@markup.emphasis' }) +vim.api.nvim_set_hl(0, '@comment.go.para', { link = '@markup.list' }) -- New highlight group +vim.api.nvim_set_hl(0, '@comment.go.keyword', { link = '@comment.note' }) + +vim.api.nvim_set_hl(0, '@bold.comment', { bold = true }) +vim.api.nvim_set_hl(0, '@italic.comment', { italic = true }) +vim.api.nvim_set_hl(0, '@underline.comment', { underline = true }) +vim.api.nvim_set_hl(0, '@strikethrough.comment', { strikethrough = true }) +vim.api.nvim_set_hl(0, '@markup.link.label.markdown_inline', { underline = true }) +vim.api.nvim_set_hl(0, '@markup.link.label', { underline = true, fg = 'blue' }) + +vim.api.nvim_set_hl(0, '@comment.documentation.go', { link = '@comment.note' }) + return comment diff --git a/lua/go/null_ls.lua b/lua/go/null_ls.lua index f6f7502ed..359cef36b 100644 --- a/lua/go/null_ls.lua +++ b/lua/go/null_ls.lua @@ -14,7 +14,6 @@ end local severities = h.diagnostics.severities --{ error = 1, warning = 2, information = 3, hint = 4 } local function handler() - return function(msg, done) local diags = {} trace('hdlr called', msg, done) @@ -163,7 +162,7 @@ local function handler() vfn.setqflist({}, ' ', { title = 'gotest', lines = qf, efm = efm }) trace(qf, efm) end - trace(diags) + log(diags) if #diags > 0 or test_failed then vim.schedule(function() @@ -190,7 +189,8 @@ return { url = 'https://golangci-lint.run/', description = 'A Go linter aggregator.', }, - method = _GO_NVIM_CFG.null_ls.golangci_lint.method or { DIAGNOSTICS_ON_OPEN, DIAGNOSTICS_ON_SAVE }, + method = _GO_NVIM_CFG.null_ls.golangci_lint.method + or { DIAGNOSTICS_ON_OPEN, DIAGNOSTICS_ON_SAVE }, filetypes = { 'go' }, generator_opts = { command = 'golangci-lint', @@ -295,8 +295,7 @@ return { -- filename = u.path.join(cwd, d.Pos.Filename), bufnr = bufnr, message = d.Text, - severity = _GO_NVIM_CFG.null_ls.golangci_lint.severity - or severities.hint, + severity = _GO_NVIM_CFG.null_ls.golangci_lint.severity or severities.hint, }) end end diff --git a/lua/go/ts/utils.lua b/lua/go/ts/utils.lua index d07994ecd..79778590d 100644 --- a/lua/go/ts/utils.lua +++ b/lua/go/ts/utils.lua @@ -221,11 +221,29 @@ function M.list_definitions_toc(bufnr) end return loc_list - -- vim.fn.setloclist(winnr, loc_list, "r") - -- -- The title needs to end with `TOC`, - -- -- so Neovim displays it like a TOC instead of an error list. - -- vim.fn.setloclist(winnr, {}, "a", { title = "Definitions TOC" }) - -- api.nvim_command "lopen" end +local node_from_match + +if vim.fn.has('nvim-0.11') == 1 then + -- for 0.11 iter_matches returns a table of TSNode[] + ---@param match table + ---@param capture_index integer + node_from_match = function(match, capture_index) + local nodes = match[capture_index] + if nodes ~= nil then + return nodes[1] + else + return nil + end + end +else + ---@param match table + ---@param capture_index integer + node_from_match = function(match, capture_index) + return match[capture_index] + end +end + +M.node_from_match = node_from_match return M diff --git a/lua/go/utils.lua b/lua/go/utils.lua index 26e94f10f..dcb1b5647 100644 --- a/lua/go/utils.lua +++ b/lua/go/utils.lua @@ -863,21 +863,6 @@ utils.throttle = function(func, duration) return inner, timer end --- function M.debounce_trailing(ms, fn) --- local timer = uv.new_timer() --- return function(...) --- local argv = { ... } --- if timer:is_active() then --- timer:stop() --- return --- end --- timer:start(ms, 0, function() --- timer:stop() --- fn(unpack(argv)) --- end) --- end --- end --- utils.debounce = function(func, ms) local timer = uv.new_timer() local function inner(...) @@ -898,7 +883,7 @@ utils.extract_filepath = function(msg, pkg_path) msg = msg or '' -- util.log(msg) --[[ or [[ findAllSubStr_test.go:234: Error inserting caseResult1: operation error DynamoDB: PutItem, exceeded maximum number of attempts]] - -- or 'path/path2/filename.go:50:11: Error invaild + -- or 'path/path2/filename.go:50:11: Error invalid -- or /home/ray/go/src/github/sample/app/driver.go:342 +0x19e5 local ma = fn.matchlist(msg, [[\v\s*(\w+.+\.go):(\d+):]]) ma = ma or fn.matchlist(msg, [[\v\s*(\w+.+\.go):(\d+)]]) diff --git a/lua/tests/go_comment_spec.lua b/lua/tests/go_comment_spec.lua index 6d731b90f..52b722a81 100644 --- a/lua/tests/go_comment_spec.lua +++ b/lua/tests/go_comment_spec.lua @@ -22,12 +22,12 @@ describe('should get nodes ', function() it('should get struct playlist and generate comments', function() vim.fn.setpos('.', { bufn, 20, 14, 0 }) local query = require('go.comment').gen(20, 14) - eq('// createPlaylist function  ', query) + eq('// createPlaylist function  ', query) end) it('should get struct playlist and generate comments', function() vim.fn.setpos('.', { bufn, 14, 4, 0 }) local query = require('go.comment').gen(14, 4) - eq('// playlist struct  ', query) + eq('// playlist struct  ', query) end) end) diff --git a/queries/comment/highlights.scm b/queries/comment/highlights.scm new file mode 100644 index 000000000..49e2e04a5 --- /dev/null +++ b/queries/comment/highlights.scm @@ -0,0 +1,11 @@ +; extends + +;; Match **bold** and __bold__ in comment text with higher priority +("text" @bold + (#match? @bold "(\\*\\*|__)[^\\*\\_]+(\\*\\*|__)") + (#set! priority 126)) ;; Set priority higher than default + +;; Match ~~strikethrough~~ in comment text with higher priority +("text" @strikethrough + (#match? @strikethrough "\\~\\~[^\\~]+\\~\\~") + (#set! priority 126)) diff --git a/after/queries/go/injections.scm b/queries/go/injections.scm similarity index 92% rename from after/queries/go/injections.scm rename to queries/go/injections.scm index 5d5affcd8..8b7845f18 100644 --- a/after/queries/go/injections.scm +++ b/queries/go/injections.scm @@ -106,3 +106,13 @@ (#lua-match? @injection.content "^`[\n|\t| ]*\{.*\}[\n|\t| ]*`$") (#offset! @injection.content 0 1 0 -1) (#set! injection.language "json"))) + +((comment) @injection.content @nospell + (#match? @injection.content "^//\\s*[#\\*-]+\\s+.+$") + (#offset! @injection.content 0 2 0 1) + (#set! injection.language "markdown")) + +((comment) @injection.content @nospell + (#match? @injection.content "^//.*\\[.*\\].*$") + (#offset! @injection.content 0 2 0 1) + (#set! injection.language "markdown")) diff --git a/after/queries/go/locals.scm b/queries/go/locals.scm similarity index 100% rename from after/queries/go/locals.scm rename to queries/go/locals.scm