--- /dev/null
+--- 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,
+})