From: Lukas Hägele Date: Sun, 11 Oct 2026 13:52:36 +0000 (+0200) Subject: add treesitter plugin to highlight identical identifiers X-Git-Url: https://git.lhaegele.de/?a=commitdiff_plain;h=80539c02edb39a526e072f69094fb240f33d1c80;p=dotfiles_nvim.git add treesitter plugin to highlight identical identifiers --- diff --git a/plugin/treesitter/highlight-identifiers.lua b/plugin/treesitter/highlight-identifiers.lua new file mode 100644 index 0000000..c399fa2 --- /dev/null +++ b/plugin/treesitter/highlight-identifiers.lua @@ -0,0 +1,63 @@ +local ns = vim.api.nvim_create_namespace("ts_highlight_identifiers") + +local function highlight_matching_identifiers() + local bufnr = vim.api.nvim_get_current_buf() + -- clear existing highlights from this namespace + vim.api.nvim_buf_clear_namespace(bufnr, ns, 0, -1) + + -- get the node under the cursor + local node = vim.treesitter.get_node() + if not node or not node:type():match("identifier") then + return + end + + -- extract its text + local text = vim.treesitter.get_node_text(node, bufnr) + if not text or text == "" then return end + + -- get the language parser and root tree + local ok_parser, parser = pcall(vim.treesitter.get_parser, bufnr) + if not ok_parser or not parser then return end + local tree = parser:parse()[1] + if not tree then return end + local root = tree:root() + + -- build a dynamic treesitter query to find all nodes of any identifier type matching the text + local lang = parser:lang() + local query_string = string.format([[ + ( + (%s) @ident + (#eq? @ident "%s") + ) + ]], node:type(), text) + + local ok_query, query = pcall(vim.treesitter.query.parse, lang, query_string) + if not ok_query or not query then return end + + -- todo: limit to current window area? + -- iterate through matches and apply extmarks + for _, match, _ in query:iter_matches(root, bufnr, 0, -1) do + for _, nodes in pairs(match) do + for _, node in ipairs(nodes) do + local start_row, start_col, end_row, end_col = node:range() + vim.api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { + end_row = end_row, + end_col = end_col, + hl_group = "Search", + }) + end + end + end +end + +-- create command +vim.api.nvim_create_user_command("HighlightIdentifiers", highlight_matching_identifiers, {}) + +-- create keymap +vim.keymap.set("n", "hi", highlight_matching_identifiers, { desc = "highlight identifier occurrences" }) + +-- delete extmarks after cursor movement +vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI", "BufEnter" }, { + desc = "delete identifier highlights after cursor movement", + callback = function() vim.api.nvim_buf_clear_namespace(0, ns, 0, -1) end +})