From df81fcda27c780b445ee8a0870c7bf84e187d8bd Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 20 Sep 2024 00:01:01 +1000 Subject: [PATCH 01/16] Comment can be colorful --- README.md | 11 ++ lua/go.lua | 8 +- lua/go/comment.lua | 251 ++++++++++++++++++++++++++++++++++++++++----- lua/go/gotest.lua | 5 +- 4 files changed, 244 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index ecbc70274..a1172d793 100644 --- a/README.md +++ b/README.md @@ -874,6 +874,17 @@ 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 = { + 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', + } + } }) ``` diff --git a/lua/go.lua b/lua/go.lua index 790c40cae..15f1babdc 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -81,9 +81,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' @@ -175,6 +177,10 @@ _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 = { + queries = nil, -- set to a table of queries to use for comment highlight see comment.lua + highlight_groups = nil + } } -- TODO: nvim_{add,del}_user_command https://github.com/neovim/neovim/pull/16752 diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 831e87828..33faaa892 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -2,48 +2,50 @@ -- 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 placeholder = _GO_NVIM_CFG.comment_placeholder or '' +local ulog = require('go.utils').log +local api = vim.api + 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 empty = vim.fn.empty + local ns = require('go.ts.go').get_package_node_at_pos() + if empty(ns) == 0 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 + ns = require('go.ts.go').get_func_method_node_at_pos() + if empty(ns) == 0 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_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 empty(ns) == 0 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 empty(ns) == 0 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 empty(ns) == 0 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 + return comment_line .. ' ' .. placeholder, ns end return comment_line, ns end @@ -55,14 +57,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 = require('go.utils').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 +72,212 @@ 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 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' then + return + end + + -- Create a namespace for the highlights + local ns_id = vim.api.nvim_create_namespace('GoCommentCode') + -- 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 = {}, + 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))) + ]], + -- Keywords are predefined in Go + -- keywords = { 'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct', 'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type', 'continue', 'for', 'import', 'return', 'var', }, + } + + 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.WARN) + return + end + + for _, match, _ in query:iter_matches(root, bufnr, 0, -1) do + local node = match[capture_index] + if node then + local name = vim.treesitter.get_node_text(node, bufnr) + target_table[name] = true + end + 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.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 '\\<\\(' .. table.concat(words, '\\|') .. '\\)\\>' + end + + local patterns = { + types = build_pattern(code_elements.types), + functions = build_pattern(code_elements.functions), + variables = build_pattern(code_elements.variables), + constants = build_pattern(code_elements.constants), + parameters = build_pattern(code_elements.parameters), + -- keywords = '\\<\\(' .. table.concat(queries.keywords, '\\|') .. '\\)\\>', + } + + -- 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 = 'GoCommentType', + functions = 'GoCommentFunction', + variables = 'GoCommentVariable', + constants = 'GoCommentConstant', + parameters = 'GoCommentParameter', + -- keywords = 'GoCommentKeyword', + } + + 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') + + -- Iterate over the captures in the query + for _, match, _ in comment_query:iter_matches(root, bufnr, 0, -1) do + local node = match[1] -- The capture is at index 1 + if node:type() == 'comment' then + 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 + + -- 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 +end + +comment.highlight = highlight_go_code_in_comments + +-- Define highlight groups for code elements within comments +vim.api.nvim_set_hl(0, 'GoCommentType', { link = 'Type' }) +vim.api.nvim_set_hl(0, 'GoCommentFunction', { link = 'Function' }) +vim.api.nvim_set_hl(0, 'GoCommentVariable', { link = 'Identifier' }) +vim.api.nvim_set_hl(0, 'GoCommentConstant', { link = 'Constant' }) +vim.api.nvim_set_hl(0, 'GoCommentParameter', { link = 'Identifier' }) -- New highlight group +vim.api.nvim_set_hl(0, 'GoCommentKeyword', { link = 'Keyword' }) + return comment diff --git a/lua/go/gotest.lua b/lua/go/gotest.lua index a880ee8fc..e8ef1c81d 100644 --- a/lua/go/gotest.lua +++ b/lua/go/gotest.lua @@ -67,9 +67,6 @@ M.efm = function() return efm end local parse = vim.treesitter.query.parse -if parse == nil then - parse = vim.treesitter.query.parse_query -end -- return "-tags=tag1,tag2" M.get_build_tags = function(args, tbl) @@ -210,7 +207,7 @@ local function cmd_builder(path, args) table.insert(cmd, optarg['P']) end - log("optargs", optarg) + log('optargs', optarg) if optarg['r'] then log('run test', optarg['r']) table.insert(cmd, '-test.run') From b5a75b711b2cd90f5bc4c54772e77118df3fb23f Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 20 Sep 2024 01:00:34 +1000 Subject: [PATCH 02/16] unit tests --- lua/go/comment.lua | 39 +++++++++++++++++++++++++++++++-------- lua/go/ts/go.lua | 7 ++----- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 33faaa892..ac7e0915b 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -2,7 +2,7 @@ -- for func name(args) rets {} -- add cmts // name : rets local comment = {} -local placeholder = _GO_NVIM_CFG.comment_placeholder or '' +local placeholder = _GO_NVIM_CFG.comment.placeholder or '' local ulog = require('go.utils').log local api = vim.api @@ -11,31 +11,30 @@ local gen_comment = function() local empty = vim.fn.empty local ns = require('go.ts.go').get_package_node_at_pos() - if empty(ns) == 0 then + if ns then -- ulog("parnode" .. vim.inspect(ns)) comments = '// Package ' .. ns.name .. ' provides ' .. ns.name return comments, ns end ns = require('go.ts.go').get_func_method_node_at_pos() - if empty(ns) == 0 then - -- ulog("parnode" .. vim.inspect(ns)) + if ns then comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end ns = require('go.ts.go').get_struct_node_at_pos() - if empty(ns) == 0 then + if ns then comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end ns = require('go.ts.go').get_interface_node_at_pos() - if empty(ns) == 0 then + if ns then -- ulog("parnode" .. vim.inspect(ns)) comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end ns = require('go.ts.go').get_type_node_at_pos() - if empty(ns) == 0 then + if ns then -- ulog("parnode" .. vim.inspect(ns)) comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns @@ -83,6 +82,8 @@ comment.gen = function() 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') @@ -91,7 +92,6 @@ local function highlight_go_code_in_comments() end -- Create a namespace for the highlights - local ns_id = vim.api.nvim_create_namespace('GoCommentCode') -- Clear any existing highlights in this namespace vim.api.nvim_buf_clear_namespace(bufnr, ns_id, 0, -1) @@ -270,7 +270,30 @@ local function highlight_go_code_in_comments() end end +local function toggle_go_comment_highlight() + _GO_NVIM_CFG.comment.enable_highlight = not _GO_NVIM_CFG.comment.enable_highlight + if _GO_NVIM_CFG.comment.enable_highlight then + highlight_go_code_in_comments() + 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, {}) + +vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'TextChanged', 'InsertLeave' }, { + pattern = { '*.go' }, + callback = function() + if _GO_NVIM_CFG.comment.enable_highlight then + require('go.comment').highlight() + end + end, +}) -- Define highlight groups for code elements within comments vim.api.nvim_set_hl(0, 'GoCommentType', { link = 'Type' }) diff --git a/lua/go/ts/go.lua b/lua/go/ts/go.lua index 774d37bec..9b58854f8 100644 --- a/lua/go/ts/go.lua +++ b/lua/go/ts/go.lua @@ -183,14 +183,11 @@ M.get_func_method_node_at_pos = function(bufnr) local bufn = bufnr or vim.api.nvim_get_current_buf() local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn) - if ns == nil then - return nil - end if ns == nil then warn('function not found') - else - return ns[#ns] + return nil end + return ns[#ns] end M.get_tbl_testcase_node_name = function(bufnr) From 4fb6d120b36240ff90e7e09b98ab761640dd442e Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 20 Sep 2024 01:19:23 +1000 Subject: [PATCH 03/16] update comment.lua setup --- README.md | 2 +- lua/go.lua | 8 +++++++- lua/go/comment.lua | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1172d793..9a6aa7ec7 100644 --- a/README.md +++ b/README.md @@ -762,7 +762,6 @@ require('go').setup({ tag_options = 'json=omitempty', -- sets options sent to gomodifytags, i.e., json=omitempty gotests_template = "", -- sets gotests -template parameter (check gotests for details) gotests_template_dir = "", -- sets gotests -template_dir parameter (check gotests for details) - 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_cfg = false, -- true: use non-default gopls setup specified in go/lsp.lua @@ -875,6 +874,7 @@ require('go').setup({ 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. 󰟓     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 diff --git a/lua/go.lua b/lua/go.lua index 15f1babdc..580d68516 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -17,7 +17,6 @@ _GO_NVIM_CFG = { gotests_template = '', -- sets gotests -template parameter (check gotests for details) gotests_template_dir = '', -- sets gotests -template_dir parameter (check gotests for details) - 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, @@ -178,6 +177,8 @@ _GO_NVIM_CFG = { 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 = '  ', + enable_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 } @@ -222,6 +223,10 @@ function go.setup(cfg) vim.log.levels.WARN ) end + if cfg.comment_placeholder ~= nil then + vim.notify('go.nvim comment_placeholder deprecated, use comment.placeholder', vim.log.levels.WARN) + cfg.comment.placeholder = cfg.comment_placeholder + end if cfg.goimport ~= nil then vim.notify('go.nvim goimport deprecated, use goimports', vim.log.levels.WARN) cfg.goimports = cfg.goimport @@ -254,6 +259,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 ac7e0915b..22c093c22 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -43,7 +43,7 @@ local gen_comment = function() end local wrap_comment = function(comment_line, ns) - if string.len(comment_line) > 0 and placeholder ~= nil and string.len(placeholder) > 0 then + if string.len(comment_line) > 0 and string.len(placeholder) > 0 then return comment_line .. ' ' .. placeholder, ns end return comment_line, ns From 59f3fdc9db91fc874cf01f51996d24d449307ba3 Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 20 Sep 2024 01:44:05 +1000 Subject: [PATCH 04/16] update spec --- lua/go.lua | 2 +- lua/go/comment.lua | 1 - lua/tests/go_comment_spec.lua | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lua/go.lua b/lua/go.lua index 580d68516..1f9e54b18 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -177,7 +177,7 @@ _GO_NVIM_CFG = { 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 = '  ', + placeholder = '  ', enable_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 diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 22c093c22..2767255dc 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -9,7 +9,6 @@ local api = vim.api local gen_comment = function() local comments = nil - local empty = vim.fn.empty local ns = require('go.ts.go').get_package_node_at_pos() if ns then -- ulog("parnode" .. vim.inspect(ns)) 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) From 572d852dd10de0e328278551ea11631bffc60add Mon Sep 17 00:00:00 2001 From: ray-x Date: Fri, 20 Sep 2024 02:00:24 +1000 Subject: [PATCH 05/16] disable hightlight comment by default --- doc/go.txt | 7 ++++++- lua/go.lua | 2 +- lua/go/comment.lua | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/go.txt b/doc/go.txt index acfc4d988..639f15143 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 = '  ', + enable_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 1f9e54b18..1ef362c62 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -178,7 +178,7 @@ _GO_NVIM_CFG = { iferr_vertical_shift = 4, -- defines where the cursor will end up vertically from the begining of if err statement after GoIfErr command comment = { placeholder = '  ', - enable_highlight = true, -- set to false to disable + enable_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 } diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 2767255dc..49300ec2a 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -86,7 +86,7 @@ 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' then + if ft ~= 'go' or not _GO_NVIM_CFG.comment.enable_highlight then return end From d3f9b2880b290683573530c8ae6f61ca3e6f1bc2 Mon Sep 17 00:00:00 2001 From: ray-x Date: Sun, 22 Sep 2024 12:08:43 +1000 Subject: [PATCH 06/16] update highlights --- doc/go.txt | 2 +- lua/go.lua | 11 +++++++---- lua/go/comment.lua | 27 ++++++++++++++------------- lua/go/null_ls.lua | 9 ++++----- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/doc/go.txt b/doc/go.txt index 639f15143..effa14c04 100644 --- a/doc/go.txt +++ b/doc/go.txt @@ -459,7 +459,7 @@ You can setup go.nvim with following options: iferr_vertical_shift = 4 -- defines where the cursor will end up vertically from the begining of if err statement after GoIfErr command comment = { placeholder = '  ', - enable_highlight = true, -- set to false to disable + 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 } diff --git a/lua/go.lua b/lua/go.lua index 1ef362c62..847bb09c2 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -178,10 +178,10 @@ _GO_NVIM_CFG = { iferr_vertical_shift = 4, -- defines where the cursor will end up vertically from the begining of if err statement after GoIfErr command comment = { placeholder = '  ', - enable_highlight = false, -- set to true to disable + 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_groups = nil, + }, } -- TODO: nvim_{add,del}_user_command https://github.com/neovim/neovim/pull/16752 @@ -224,7 +224,10 @@ function go.setup(cfg) ) end if cfg.comment_placeholder ~= nil then - vim.notify('go.nvim comment_placeholder deprecated, use comment.placeholder', vim.log.levels.WARN) + vim.notify( + 'go.nvim comment_placeholder deprecated, use comment.placeholder', + vim.log.levels.WARN + ) cfg.comment.placeholder = cfg.comment_placeholder end if cfg.goimport ~= nil then diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 49300ec2a..6e6f035a0 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -86,7 +86,7 @@ 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.enable_highlight then + if ft ~= 'go' or not _GO_NVIM_CFG.comment.highlight then return end @@ -131,6 +131,7 @@ local function highlight_go_code_in_comments() ]], -- Keywords are predefined in Go -- keywords = { 'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct', 'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type', 'continue', 'for', 'import', 'return', 'var', }, + keywords = { 'func', 'interface', 'defer', 'go', 'map', 'struct', 'chan', 'package', 'const', 'returns'}, } if _GO_NVIM_CFG.comment.queries then @@ -191,7 +192,7 @@ local function highlight_go_code_in_comments() variables = build_pattern(code_elements.variables), constants = build_pattern(code_elements.constants), parameters = build_pattern(code_elements.parameters), - -- keywords = '\\<\\(' .. table.concat(queries.keywords, '\\|') .. '\\)\\>', + keywords = '\\<\\(' .. table.concat(queries.keywords, '\\|') .. '\\)\\>', } -- Compile regexes @@ -209,7 +210,7 @@ local function highlight_go_code_in_comments() variables = 'GoCommentVariable', constants = 'GoCommentConstant', parameters = 'GoCommentParameter', - -- keywords = 'GoCommentKeyword', + keywords = 'GoCommentKeyword', } if _GO_NVIM_CFG.comment.highlight_groups then @@ -270,8 +271,8 @@ local function highlight_go_code_in_comments() end local function toggle_go_comment_highlight() - _GO_NVIM_CFG.comment.enable_highlight = not _GO_NVIM_CFG.comment.enable_highlight - if _GO_NVIM_CFG.comment.enable_highlight then + _GO_NVIM_CFG.comment.highlight = not _GO_NVIM_CFG.comment.highlight + if _GO_NVIM_CFG.comment.highlight then highlight_go_code_in_comments() else vim.api.nvim_buf_clear_namespace(0, ns_id, 0, -1) @@ -285,21 +286,21 @@ vim.api.nvim_create_user_command('ToggleGoCommentHighlight', function() require('go.comment').toggle_highlight() end, {}) -vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'TextChanged', 'InsertLeave' }, { +vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'WinEnter', 'TextChanged', 'InsertLeave' }, { pattern = { '*.go' }, callback = function() - if _GO_NVIM_CFG.comment.enable_highlight then + if _GO_NVIM_CFG.comment.highlight then require('go.comment').highlight() end end, }) -- Define highlight groups for code elements within comments -vim.api.nvim_set_hl(0, 'GoCommentType', { link = 'Type' }) -vim.api.nvim_set_hl(0, 'GoCommentFunction', { link = 'Function' }) -vim.api.nvim_set_hl(0, 'GoCommentVariable', { link = 'Identifier' }) -vim.api.nvim_set_hl(0, 'GoCommentConstant', { link = 'Constant' }) -vim.api.nvim_set_hl(0, 'GoCommentParameter', { link = 'Identifier' }) -- New highlight group -vim.api.nvim_set_hl(0, 'GoCommentKeyword', { link = 'Keyword' }) +vim.api.nvim_set_hl(0, 'GoCommentType', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, 'GoCommentFunction', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, 'GoCommentVariable', { link = '@markup.emphasis' }) +vim.api.nvim_set_hl(0, 'GoCommentConstant', { link = '@markup.emphasis' }) +vim.api.nvim_set_hl(0, 'GoCommentParameter', { link = '@markup.list' }) -- New highlight group +vim.api.nvim_set_hl(0, 'GoCommentKeyword', { link = '@markup.strong' }) return comment diff --git a/lua/go/null_ls.lua b/lua/go/null_ls.lua index dcf2f57b0..1aaee52c4 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) @@ -161,7 +160,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() @@ -188,7 +187,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', @@ -289,8 +289,7 @@ return { end_col = d.Pos.Column + 1, filename = u.path.join(cwd, d.Pos.Filename), 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 From fc56be6f391e791ba7a4a6a3cd480e7c220aa54d Mon Sep 17 00:00:00 2001 From: ray-x Date: Sun, 22 Sep 2024 20:13:50 +1000 Subject: [PATCH 07/16] getnodetext --- README.md | 1 + lua/go/comment.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a6aa7ec7..6033ca183 100644 --- a/README.md +++ b/README.md @@ -875,6 +875,7 @@ require('go').setup({ 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 diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 6e6f035a0..8235cc191 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -57,7 +57,7 @@ comment.gen = function() -- nothing found 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+)' From 8d66c1cb041aac7340fb28b06724e3078c0a73e5 Mon Sep 17 00:00:00 2001 From: ray-x Date: Mon, 23 Sep 2024 02:08:12 +1000 Subject: [PATCH 08/16] node_from_match neovim 0.11 --- lua/go/comment.lua | 155 +++++++++++++++++++++++++++++---------------- 1 file changed, 100 insertions(+), 55 deletions(-) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 8235cc191..79190c565 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -5,6 +5,7 @@ local comment = {} 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 @@ -106,6 +107,8 @@ local function highlight_go_code_in_comments() variables = {}, constants = {}, parameters = {}, + methods = {}, + methods_params = {}, keywords = {}, } @@ -129,9 +132,30 @@ local function highlight_go_code_in_comments() (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 = { 'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct', 'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type', 'continue', 'for', 'import', 'return', 'var', }, - keywords = { 'func', 'interface', 'defer', 'go', 'map', 'struct', 'chan', 'package', 'const', 'returns'}, + keywords = { + 'func', + 'interface', + 'defer', + 'go', + 'map', + 'struct', + 'chan', + 'package', + 'const', + 'returns', + }, } if _GO_NVIM_CFG.comment.queries then @@ -154,22 +178,24 @@ local function highlight_go_code_in_comments() end if not capture_index then - vim.notify('Capture name "' .. capture_name .. '" not found in query', vim.log.levels.WARN) + vim.notify('Capture name "' .. capture_name .. '" not found in query', vim.log.levels.INFO) return end - for _, match, _ in query:iter_matches(root, bufnr, 0, -1) do - local node = match[capture_index] - if node then - local name = vim.treesitter.get_node_text(node, bufnr) - target_table[name] = true - 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) @@ -189,9 +215,11 @@ local function highlight_go_code_in_comments() 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, '\\|') .. '\\)\\>', } @@ -207,9 +235,11 @@ local function highlight_go_code_in_comments() local highlight_groups = { types = 'GoCommentType', functions = 'GoCommentFunction', + methods = 'GoCommentMethod', variables = 'GoCommentVariable', constants = 'GoCommentConstant', parameters = 'GoCommentParameter', + methods_params = 'GoCommentParameter', keywords = 'GoCommentKeyword', } @@ -222,48 +252,59 @@ local function highlight_go_code_in_comments() -- 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 _, match, _ in comment_query:iter_matches(root, bufnr, 0, -1) do - local node = match[1] -- The capture is at index 1 - if node:type() == 'comment' then - 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 _, 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 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 - - -- 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 + 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 @@ -286,18 +327,22 @@ vim.api.nvim_create_user_command('ToggleGoCommentHighlight', function() require('go.comment').toggle_highlight() end, {}) -vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'WinEnter', 'TextChanged', 'InsertLeave' }, { - pattern = { '*.go' }, - callback = function() - if _GO_NVIM_CFG.comment.highlight then - require('go.comment').highlight() - end - end, -}) +vim.api.nvim_create_autocmd( + { 'BufEnter', 'BufWritePost', 'WinEnter', 'TextChanged', 'InsertLeave' }, + { + pattern = { '*.go' }, + callback = function() + if _GO_NVIM_CFG.comment.highlight then + require('go.comment').highlight() + end + end, + } +) -- Define highlight groups for code elements within comments vim.api.nvim_set_hl(0, 'GoCommentType', { link = '@markup.heading' }) vim.api.nvim_set_hl(0, 'GoCommentFunction', { link = '@markup.heading' }) +vim.api.nvim_set_hl(0, 'GoCommentMethod', { link = '@markup.heading' }) vim.api.nvim_set_hl(0, 'GoCommentVariable', { link = '@markup.emphasis' }) vim.api.nvim_set_hl(0, 'GoCommentConstant', { link = '@markup.emphasis' }) vim.api.nvim_set_hl(0, 'GoCommentParameter', { link = '@markup.list' }) -- New highlight group From 9a9f3cef28260bae358b39d86cd0b6d6e69a3fac Mon Sep 17 00:00:00 2001 From: ray-x Date: Mon, 23 Sep 2024 02:09:05 +1000 Subject: [PATCH 09/16] node_from_match for nvim 0.11 --- lua/go/ts/utils.lua | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) 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 From 09dfc002c137141375281381ca6465f9fefe2cc3 Mon Sep 17 00:00:00 2001 From: ray-x Date: Tue, 24 Sep 2024 23:36:51 +1000 Subject: [PATCH 10/16] debounce the highlight requests --- lua/go.lua | 1 + lua/go/comment.lua | 16 +++++++++++++--- lua/go/utils.lua | 17 +---------------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/lua/go.lua b/lua/go.lua index ac9e3efad..171cbbaaf 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -182,6 +182,7 @@ _GO_NVIM_CFG = { 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 }, } diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 79190c565..7628a820c 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -311,10 +311,15 @@ local function highlight_go_code_in_comments() 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_go_code_in_comments() + 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 @@ -327,12 +332,17 @@ 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', 'TextChanged', 'InsertLeave' }, + { 'BufEnter', 'BufWritePost', 'WinEnter', 'InsertLeave', 'CursorHold' }, { pattern = { '*.go' }, - callback = function() + group = group, + callback = function(opts) if _GO_NVIM_CFG.comment.highlight then + if opts.event == 'CursorHold' then + -- can be slow + end require('go.comment').highlight() end end, 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+)]]) From f4bb9ff173e8aba7fe732acc713021ac9410a0ef Mon Sep 17 00:00:00 2001 From: ray-x Date: Tue, 24 Sep 2024 23:41:13 +1000 Subject: [PATCH 11/16] debounce comment hl when file not changed --- lua/go/comment.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 7628a820c..c1b2f1d4c 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -1,7 +1,7 @@ -- todo -- for func name(args) rets {} -- add cmts // name : rets -local comment = {} +local comment = {hl_timestamp = {}} local placeholder = _GO_NVIM_CFG.comment.placeholder or '' local ulog = require('go.utils').log local api = vim.api @@ -340,10 +340,14 @@ vim.api.nvim_create_autocmd( group = group, callback = function(opts) if _GO_NVIM_CFG.comment.highlight then - if opts.event == 'CursorHold' then - -- can be slow + -- 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, } From 1c705c5f543ff46164d70f9bb9f7a1db0503fcc4 Mon Sep 17 00:00:00 2001 From: ray-x Date: Tue, 1 Oct 2024 19:40:57 +1000 Subject: [PATCH 12/16] embed comment highlight; default sematic token priority; comment highlight group --- README.md | 24 +++++++++++++--- after/queries/comment/highlights.scm | 21 ++++++++++++++ lua/go.lua | 17 +++++------- lua/go/comment.lua | 41 +++++++++++++++++----------- 4 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 after/queries/comment/highlights.scm diff --git a/README.md b/README.md index 8893c711d..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. @@ -891,6 +903,7 @@ require('go').setup({ } }) ``` +
You will need to add keybind yourself: e.g @@ -922,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/after/queries/comment/highlights.scm b/after/queries/comment/highlights.scm new file mode 100644 index 000000000..c6906dfae --- /dev/null +++ b/after/queries/comment/highlights.scm @@ -0,0 +1,21 @@ +; extends + +;; Match **bold** and __bold__ in comment text with higher priority +("text" @comment.bold + (#match? @comment.bold "(\\*\\*|__)[^\\*\\_]+(\\*\\*|__)") + (#set! priority 126)) ;; Set priority higher than default + +;; Match *italic* and _italic_ in comment text with higher priority +("text" @comment.italic + (#match? @comment.italic "(\\*|_)[^\\*\\_]+(\\*|_)") + (#set! priority 130)) + +;; Match ~~strikethrough~~ in comment text with higher priority +("text" @comment.strikethrough + (#match? @comment.strikethrough "~~[^~]+~~") + (#set! priority 126)) + +;; Match [text] in comment text nodes (reference links) with higher priority +("text" @comment.link + (#match? @comment.link "\\[[^\\]]+\\]") + (#set! priority 126)) diff --git a/lua/go.lua b/lua/go.lua index 9dfe05122..e1b04d2b7 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -26,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, @@ -237,15 +239,6 @@ function go.setup(cfg) 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 - vim.notify( - 'go.nvim lsp_diag_virtual_text deprecated, use diagnostic.virtual_text', - vim.log.levels.WARN - ) - end - if cfg.lsp_diag_signs ~= nil then - vim.notify('go.nvim lsp_diag_signs deprecated, use diagnostic.signs', vim.log.levels.WARN) - end if cfg.disable_defaults then reset_tbl(_GO_NVIM_CFG) _GO_NVIM_CFG.disable_defaults = true @@ -257,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 diff --git a/lua/go/comment.lua b/lua/go/comment.lua index c1b2f1d4c..9c00f97b5 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -1,7 +1,7 @@ -- todo -- for func name(args) rets {} -- add cmts // name : rets -local comment = {hl_timestamp = {}} +local comment = { hl_timestamp = {} } local placeholder = _GO_NVIM_CFG.comment.placeholder or '' local ulog = require('go.utils').log local api = vim.api @@ -233,14 +233,14 @@ local function highlight_go_code_in_comments() -- Define the highlight groups for each category local highlight_groups = { - types = 'GoCommentType', - functions = 'GoCommentFunction', - methods = 'GoCommentMethod', - variables = 'GoCommentVariable', - constants = 'GoCommentConstant', - parameters = 'GoCommentParameter', - methods_params = 'GoCommentParameter', - keywords = 'GoCommentKeyword', + 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', } if _GO_NVIM_CFG.comment.highlight_groups then @@ -354,12 +354,21 @@ vim.api.nvim_create_autocmd( ) -- Define highlight groups for code elements within comments -vim.api.nvim_set_hl(0, 'GoCommentType', { link = '@markup.heading' }) -vim.api.nvim_set_hl(0, 'GoCommentFunction', { link = '@markup.heading' }) -vim.api.nvim_set_hl(0, 'GoCommentMethod', { link = '@markup.heading' }) -vim.api.nvim_set_hl(0, 'GoCommentVariable', { link = '@markup.emphasis' }) -vim.api.nvim_set_hl(0, 'GoCommentConstant', { link = '@markup.emphasis' }) -vim.api.nvim_set_hl(0, 'GoCommentParameter', { link = '@markup.list' }) -- New highlight group -vim.api.nvim_set_hl(0, 'GoCommentKeyword', { link = '@markup.strong' }) +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 = '@markup.strong' }) + +vim.api.nvim_set_hl(0, '@comment.bold.comment', { bold = true }) +vim.api.nvim_set_hl(0, '@comment.italic.comment', { italic = true }) +vim.api.nvim_set_hl(0, '@comment.underline.comment', { underline = true }) +vim.api.nvim_set_hl(0, '@comment.strikethrough.comment', { strikethrough = true }) +vim.api.nvim_set_hl(0, '@comment.link.inline.comment', { underline = true }) +vim.api.nvim_set_hl(0, '@comment.link.reference.comment', { underline = true }) + +vim.api.nvim_set_hl(0, '@comment.documentation.go', { link = '@comment.note' }) return comment From 08dd45c4e4651cbf2ffa71d20c49de8fe0bb1e9c Mon Sep 17 00:00:00 2001 From: ray-x Date: Wed, 9 Oct 2024 12:38:31 +1100 Subject: [PATCH 13/16] moves file around --- lua/go/comment.lua | 10 +++++++--- .../queries => queries}/comment/highlights.scm | 6 +++--- {after/queries => queries}/go/injections.scm | 16 ++++++++++++++-- {after/queries => queries}/go/locals.scm | 0 4 files changed, 24 insertions(+), 8 deletions(-) rename {after/queries => queries}/comment/highlights.scm (87%) rename {after/queries => queries}/go/injections.scm (89%) rename {after/queries => queries}/go/locals.scm (100%) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 9c00f97b5..e5ae9ac81 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -143,18 +143,19 @@ local function highlight_go_code_in_comments() name: (identifier) @param_name))) ]], -- Keywords are predefined in Go - -- keywords = { 'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct', 'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type', 'continue', 'for', 'import', 'return', 'var', }, keywords = { 'func', 'interface', 'defer', - 'go', 'map', 'struct', 'chan', 'package', 'const', 'returns', + '+build', + 'go:build', + 'go:generate', }, } @@ -209,7 +210,7 @@ local function highlight_go_code_in_comments() if #words == 0 then return nil end - return '\\<\\(' .. table.concat(words, '\\|') .. '\\)\\>' + return '\\C\\<\\(' .. table.concat(words, '\\|') .. '\\)\\>' end local patterns = { @@ -221,6 +222,8 @@ local function highlight_go_code_in_comments() 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 @@ -241,6 +244,7 @@ local function highlight_go_code_in_comments() 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 diff --git a/after/queries/comment/highlights.scm b/queries/comment/highlights.scm similarity index 87% rename from after/queries/comment/highlights.scm rename to queries/comment/highlights.scm index c6906dfae..37041db4a 100644 --- a/after/queries/comment/highlights.scm +++ b/queries/comment/highlights.scm @@ -16,6 +16,6 @@ (#set! priority 126)) ;; Match [text] in comment text nodes (reference links) with higher priority -("text" @comment.link - (#match? @comment.link "\\[[^\\]]+\\]") - (#set! priority 126)) +; ("text" @comment.link +; (#match? @comment.link "\s\\[.+\\]\s") +; (#set! priority 126)) diff --git a/after/queries/go/injections.scm b/queries/go/injections.scm similarity index 89% rename from after/queries/go/injections.scm rename to queries/go/injections.scm index 62330867e..c1247ac0a 100644 --- a/after/queries/go/injections.scm +++ b/queries/go/injections.scm @@ -107,6 +107,18 @@ (#offset! @injection.content 0 1 0 -1) (#set! injection.language "json"))) - +;; inject markdown style heading start with # +((comment) @injection.content + (#match? @injection.content "^//\\s*[\#]+.+") + (#offset! @injection.content 0 2 0 -1) + (#set! injection.language "markdown")) + +;; inject markdown list +; ((comment) @injection.content +; (#match? @injection.content "^//\\s*[\-|\*]\\s*.+$") +; (#offset! @injection.content 0 2 0 -1) +; (#set! injection.language "markdown")) ((comment) @injection.content - (#set! injection.language "comment")) + (#match? @injection.content "^//\\s*-.+") + (#offset! @injection.content 0 2 0 0) + (#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 From 2f24e3f349d19f3c3ce3358b06e3328b0fa940b3 Mon Sep 17 00:00:00 2001 From: ray-x Date: Wed, 9 Oct 2024 15:55:17 +1100 Subject: [PATCH 14/16] link highlight with markdown --- queries/comment/highlights.scm | 18 ++++-------------- queries/go/injections.scm | 24 +++++++++--------------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/queries/comment/highlights.scm b/queries/comment/highlights.scm index 37041db4a..49e2e04a5 100644 --- a/queries/comment/highlights.scm +++ b/queries/comment/highlights.scm @@ -1,21 +1,11 @@ ; extends ;; Match **bold** and __bold__ in comment text with higher priority -("text" @comment.bold - (#match? @comment.bold "(\\*\\*|__)[^\\*\\_]+(\\*\\*|__)") +("text" @bold + (#match? @bold "(\\*\\*|__)[^\\*\\_]+(\\*\\*|__)") (#set! priority 126)) ;; Set priority higher than default -;; Match *italic* and _italic_ in comment text with higher priority -("text" @comment.italic - (#match? @comment.italic "(\\*|_)[^\\*\\_]+(\\*|_)") - (#set! priority 130)) - ;; Match ~~strikethrough~~ in comment text with higher priority -("text" @comment.strikethrough - (#match? @comment.strikethrough "~~[^~]+~~") +("text" @strikethrough + (#match? @strikethrough "\\~\\~[^\\~]+\\~\\~") (#set! priority 126)) - -;; Match [text] in comment text nodes (reference links) with higher priority -; ("text" @comment.link -; (#match? @comment.link "\s\\[.+\\]\s") -; (#set! priority 126)) diff --git a/queries/go/injections.scm b/queries/go/injections.scm index c1247ac0a..8b7845f18 100644 --- a/queries/go/injections.scm +++ b/queries/go/injections.scm @@ -107,18 +107,12 @@ (#offset! @injection.content 0 1 0 -1) (#set! injection.language "json"))) -;; inject markdown style heading start with # -((comment) @injection.content - (#match? @injection.content "^//\\s*[\#]+.+") - (#offset! @injection.content 0 2 0 -1) - (#set! injection.language "markdown")) - -;; inject markdown list -; ((comment) @injection.content -; (#match? @injection.content "^//\\s*[\-|\*]\\s*.+$") -; (#offset! @injection.content 0 2 0 -1) -; (#set! injection.language "markdown")) -((comment) @injection.content - (#match? @injection.content "^//\\s*-.+") - (#offset! @injection.content 0 2 0 0) - (#set! injection.language "markdown")) +((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")) From 0b52c6066fc4fe07b2f9af154fa2da5d466bdf94 Mon Sep 17 00:00:00 2001 From: ray-x Date: Wed, 9 Oct 2024 16:39:12 +1100 Subject: [PATCH 15/16] update highlight --- lua/go/comment.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index e5ae9ac81..57874aebb 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -223,7 +223,7 @@ local function highlight_go_code_in_comments() 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 = '\\[\\([^\\[\\]]*\\)\\]', + -- matchbrackets = '\\[\\([^\\[\\]]*\\)\\]', } -- Compile regexes @@ -366,12 +366,12 @@ 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 = '@markup.strong' }) -vim.api.nvim_set_hl(0, '@comment.bold.comment', { bold = true }) -vim.api.nvim_set_hl(0, '@comment.italic.comment', { italic = true }) -vim.api.nvim_set_hl(0, '@comment.underline.comment', { underline = true }) -vim.api.nvim_set_hl(0, '@comment.strikethrough.comment', { strikethrough = true }) -vim.api.nvim_set_hl(0, '@comment.link.inline.comment', { underline = true }) -vim.api.nvim_set_hl(0, '@comment.link.reference.comment', { underline = true }) +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' }) From 77cef34c929713fcadaf03e17ab19234856541a2 Mon Sep 17 00:00:00 2001 From: ray-x Date: Thu, 17 Oct 2024 11:05:49 +1100 Subject: [PATCH 16/16] add deprecated --- lua/go/comment.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 57874aebb..2a423e13c 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -156,6 +156,7 @@ local function highlight_go_code_in_comments() '+build', 'go:build', 'go:generate', + 'Deprecated', }, } @@ -364,7 +365,7 @@ 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 = '@markup.strong' }) +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 })