diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-21 16:05:21 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-21 16:05:21 +0200 |
| commit | b413d9c470f3597be1a51b52e58c854db5f31bd2 (patch) | |
| tree | dec198b28121792107e551e1ca86823e3b67cb33 | |
| parent | 19bf0d5cd95a2643736dd35d7b127c7d023429cf (diff) | |
| download | dotfiles-b413d9c470f3597be1a51b52e58c854db5f31bd2.tar.gz dotfiles-b413d9c470f3597be1a51b52e58c854db5f31bd2.zip | |
fix(nvim): live highlight TODO strings
Previously, extended marks for TODO strings were only set once on
`'FileType'`.
| -rw-r--r-- | .config/nvim/plugin/50-extmarks.lua | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/.config/nvim/plugin/50-extmarks.lua b/.config/nvim/plugin/50-extmarks.lua index c11d10c..1324da0 100644 --- a/.config/nvim/plugin/50-extmarks.lua +++ b/.config/nvim/plugin/50-extmarks.lua @@ -37,7 +37,7 @@ end local function pmatches(lines, pattern) local col1, col2, row = nil, nil, 1 return function() - while row < #lines do + while row <= #lines do col1, col2 = string.find(lines[row], pattern, (col2 or 0) + 1) if col1 then return { col1 = col1, col2 = col2, row = row } @@ -55,18 +55,18 @@ end -- predicate: is passed row and col, if true then set the mark -- hl_group: highlight group -- } -local function set_extmarks(next_pos, opts) +local function set_extmarks(buf, next_pos, opts) for pos in next_pos do local marks = vim.api.nvim_buf_get_extmarks( - 0, + buf, opts.ns, { pos.row - 1, pos.col1 - 1 }, { pos.row - 1, pos.col2 - 1 }, {} ) - if #marks == 0 and opts.predicate(pos.row - 1, pos.col1 - 1) then + if #marks == 0 and opts.predicate(buf, pos.row - 1, pos.col1 - 1) then vim.api.nvim_buf_set_extmark( - 0, + buf, opts.ns, pos.row - 1, pos.col1 - 1, @@ -79,11 +79,11 @@ end -- TODO a better way to do this: -- For code, only check in "comment" node ranges -- For non-code, do it per type. For Markdown, only check "paragraph" nodes -local function hl_todo_predicate(row, col) - if vim.o.filetype == "markdown" or vim.treesitter.get_parser() == nil then +local function hl_todo_predicate(buf, row, col) + if vim.bo[buf].filetype == "markdown" or vim.treesitter.get_parser(buf) == nil then return true end - local node = assert(vim.treesitter.get_node({ pos = { row, col } })) + local node = assert(vim.treesitter.get_node({ bufnr = buf, pos = { row, col } })) return node_within_type(node, "comment") end @@ -94,12 +94,36 @@ local extmarks_todo_opts = { predicate = hl_todo_predicate, } --- Initialize extmarks +local function scan(buf, first, last) + local lines = vim.api.nvim_buf_get_lines(buf, first, last, false) + local iter = pmatches(lines, patterns.todo) + set_extmarks(buf, function() + local pos = iter() + if pos then + pos.row = pos.row + first + end + return pos + end, extmarks_todo_opts) +end + vim.api.nvim_create_autocmd("FileType", { - desc = "Initialize extmarks", + desc = "Initialize and watch TODO extmarks", group = vim.g.dotfiles.augroup, - callback = function() - local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) - set_extmarks(pmatches(lines, patterns.todo), extmarks_todo_opts) + callback = function(args) + local buf = args.buf + scan(buf, 0, -1) + if vim.b[buf].dotfiles_todo_attached then + return + end + vim.b[buf].dotfiles_todo_attached = true + vim.api.nvim_buf_attach(buf, false, { + on_lines = function(_, b, _, first, _, last_new) + vim.schedule(function() + if vim.api.nvim_buf_is_valid(b) then + scan(b, first, last_new) + end + end) + end, + }) end, }) |
