From: Lukas Hägele Date: Sun, 18 Oct 2026 10:32:53 +0000 (+0200) Subject: add treesitter plugin to colorize keywords in comments X-Git-Url: https://git.lhaegele.de/?a=commitdiff_plain;h=5439343fcd477543032e8c6ebb0962ef04a6c7af;p=dotfiles_nvim.git add treesitter plugin to colorize keywords in comments --- diff --git a/plugin/treesitter/comment-keywords.lua b/plugin/treesitter/comment-keywords.lua new file mode 100644 index 0000000..610e0fa --- /dev/null +++ b/plugin/treesitter/comment-keywords.lua @@ -0,0 +1,77 @@ +--- inspiration from: https://caseymuratori.com/blog_0023 +--- +--- "I will often put “TODO” comments in code that look like this, where it is not really a thing that I need to do, +--- but rather is a note about the general state of the codebase that I would like someone, during final analysis before shipping, +--- to read, consider, and then either remove or act on. +--- In my own codebase, I actually have a few different keywords that I use to differentiate comment types. +--- Every single comment begins with one of them. +--- They are: +--- +--- // NOTE(casey): +--- A comment by me that does not fall into any other category (most comments are this kind). +--- +--- // IMPORTANT(casey): +--- A key comment that describes a very important idea about the code that must be read and fully understood by anyone who is going to touch it. +--- +--- // TODO(casey): +--- Something I need to do. +--- +--- // STUDY(casey): +--- Something I need to look at in more detail in the future, because I believe the code contains an opportunity to advance the way I program. + +-- namespace +local ns_id = vim.api.nvim_create_namespace("comment_keywords") + +local function update_extmarks() + local winid = vim.api.nvim_get_current_win() + local bufnr = vim.api.nvim_get_current_buf() + + local parser = vim.treesitter.get_parser(bufnr, "c") + if not parser then + vim.notify("currently only 'C' is supported", vim.log.levels.INFO) + return + end + + -- delete old extmarks + vim.api.nvim_buf_clear_namespace(bufnr, ns_id, 0, -1) + + -- parse tree + local tree = parser:parse()[1] + local root = tree:root() + + local query = vim.treesitter.query.parse("c", "(comment) @comment") + + -- get currently visible window area + local top_line = vim.fn.line("w0", winid) - 1 + local bot_line = vim.fn.line("w$", winid) + + -- iterate query within visible area + for id, node in query:iter_captures(root, bufnr, top_line, bot_line) do + local start_row, _, _, _ = node:range() + local lines = vim.api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false) + local text = lines[1] or "" + + local map = { + ["todo"] = "@comment.todo", + ["note"] = "@comment.note", + ["important"] = "@comment.warning", + ["study"] = "@comment.info", + } + for k, v in pairs(map) do + local start_col, end_col = text:lower():find(k) + if start_col then + pcall(vim.api.nvim_buf_set_extmark, bufnr, ns_id, start_row, start_col - 1, { + end_col = end_col, + hl_group = v + }) + break + end + end + end +end + +-- update extmarks after cursor movement +vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI", "BufEnter" }, { + pattern = {"*.c", "*.h"}, + callback = update_extmarks, +})