Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: highlight is broken with multiple capture groups in opts.highlight.pattern #326

Open
4 tasks done
h3xOo opened this issue Oct 15, 2024 · 1 comment
Open
4 tasks done
Labels
bug Something isn't working stale

Comments

@h3xOo
Copy link

h3xOo commented Oct 15, 2024

Did you check docs and existing issues?

  • I have read all the todo-comments.nvim docs
  • I have updated the plugin to the latest version before submitting this issue
  • I have searched the existing issues of todo-comments.nvim
  • I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

NVIM v0.10.2 Build type: RelWithDebInfo LuaJIT 2.1.1727870382

Operating system/version

Artix Linux 6.11.2-artix1-1

Describe the bug

I'm trying to match optional (nickname) after keyword, but I can't get it to highlight (either it doesn't work at all, or breaks default or highlights only part of parenthesis) [or I can't just write regex 🙃). I think it might be connected with fact, that I'm using extra capture group for optional (nick), but todo-comments expects at most 2?

I've added this prints for debugging

diff --git a/lua/todo-comments/highlight.lua b/lua/todo-comments/highlight.lua
index f4c7674..9884319 100644
--- a/lua/todo-comments/highlight.lua
+++ b/lua/todo-comments/highlight.lua
@@ -45,10 +45,14 @@ function M.match(str, patterns)
 
   for _, pattern in pairs(patterns) do
     local m = vim.fn.matchlist(str, [[\v\C]] .. pattern)
+    for i, value in pairs(m) do
+      print(string.format("match[%d] = %s", i, value))
+    end
     if #m > 1 and m[2] then
       local match = m[2]
       local kw = m[3] ~= "" and m[3] or m[2]
       local start = str:find(match, 1, true)
+      print(string.format("match = %s, kw = %s\nreturning start = %d, start + #match = %d, kw = %s", match, kw, start, start + #match, kw))
       return start, start + #match, kw
     end
   end

And on file

// FIXME:
//
// FIXME(nick):

I got

match[1] = // FIXME:
match[2] = FIXME                                                                                        
match[3] =                                                                                              
match[4] =                                                                                              
match[5] =                                                                                              
match[6] =                                                                                              
match[7] =                                                                                              
match[8] =                                                                                              
match[9] =                                                                                              
match[10] =                                                                                             
match = FIXME, kw = FIXME                                                                               
returning start = 4, start + #match = 9, kw = FIXME                                                     
match[1] = // FIXME(nick):                                                                              
match[2] = FIXME                                                                                        
match[3] = (nick)                                                                                       
match[4] =                                                                                              
match[5] =                                                                                              
match[6] =                                                                                              
match[7] =                                                                                              
match[8] =                                                                                              
match[9] =                                                                                              
match[10] =                                                                                             
match = FIXME, kw = (nick)                                                                              
returning start = 4, start + #match = 9, kw = (nick)  

Interestingly, if I use vim.fn.matchadd() it works, like this:

local function get_magic_regex(name)
        return "\\v\\c\\@?" .. name .. "(\\(\\w*\\))?(:)?"
end

vim.fn.matchadd("DiagnosticInfo", get_magic_regex("todo"))
vim.fn.matchadd("DiagnosticError", get_magic_regex("fixme"))
vim.fn.matchadd("DiagnosticWarn", get_magic_regex("warning"))

But I don't like it, since it ignores any context, is very limited etc.

Steps To Reproduce

  1. Create file with comment like FIXME(cool nickname): foo and FIXME: foo. Only second one should be highlighted.

Expected Behavior

Multiple capture groups are respected

Repro

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
  spec = {
    {
      "folke/todo-comments.nvim",
      opts = function()
        -- @see: https://github.com/folke/todo-comments.nvim/blob/main/lua/todo-comments/config.lua
        local default_keywords = {
          FIX = {
            icon = "", -- icon used for the sign, and in search results
            color = "error", -- can be a hex color, or a named color (see below)
            alt = { "FIXME", "BUG", "FIXIT", "ISSUE" }, -- a set of other keywords that all map to this FIX keywords
            -- signs = false, -- configure signs for some keywords individually
          },
          TODO = { icon = "", color = "info" },
          HACK = { icon = "", color = "warning" },
          WARN = { icon = "", color = "warning", alt = { "WARNING", "XXX" } },
          PERF = { icon = "", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } },
          NOTE = { icon = "", color = "hint", alt = { "INFO" } },
          TEST = { icon = "", color = "test", alt = { "TESTING", "PASSED", "FAILED" } },
        }

        -- Custom keywords
        local keywords = {
          SEE = {
            icon = "",
            color = "info",
          },
        }

        keywords = vim.tbl_deep_extend("force", {}, default_keywords, keywords)
        -- Add lowercase versions of each keyword
        for key, val in pairs(keywords) do
          local alt = { key:lower(), key }
          if val.alt then
            for _, alt_key in ipairs(val.alt) do
              alt[#alt + 1] = alt_key
              alt[#alt + 1] = alt_key:lower()
            end
          end
          keywords[key].alt = alt
        end
        return {
          keywords = keywords,
          highlight = {
            pattern = { [[.*\@<(KEYWORDS)(\(\w*\))?\s*]], [[.*<(KEYWORDS)(\(\w*\))?\s*:]], },
          },
          search = {
            pattern = [[[\\\\@]*\b(KEYWORDS)(\s|:)]],
          }
        }
      end,
    },
  }
})
@h3xOo h3xOo added the bug Something isn't working label Oct 15, 2024
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the stale label Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stale
Projects
None yet
Development

No branches or pull requests

1 participant