add quickfix plugin to search for todos quickly
authorLukas Hägele <lukas.haegele93@web.de>
Sun, 18 Oct 2026 11:24:20 +0000 (13:24 +0200)
committerLukas Hägele <lukas.haegele93@web.de>
Sun, 18 Oct 2026 11:24:20 +0000 (13:24 +0200)
lua/snippets/find-to-quickfix.lua [new file with mode: 0644]
plugin/quickfix/project-search.lua [new file with mode: 0644]
plugin/quickfix/search-todos.lua [new file with mode: 0644]
plugin/treesitter/project-search.lua [deleted file]

diff --git a/lua/snippets/find-to-quickfix.lua b/lua/snippets/find-to-quickfix.lua
new file mode 100644 (file)
index 0000000..ad94aed
--- /dev/null
@@ -0,0 +1,58 @@
+
+local M = {}
+
+local function notify(msg, level)
+  vim.notify("(snippets/find-to-quickfix) " ..msg, level)
+end
+
+local function find_to_quickfix(word)
+  if word == "" then
+    notify("no identifier under the cursor found", vim.log.levels.WARN)
+    return
+  end
+
+  local cmd
+  local efm = "%f:%l:%c:%m" -- default error format for ripgrep
+
+  -- determine search tool (prio: ripgrep -> git grep -> grep)
+  if vim.fn.executable("rg") == 1 then
+      cmd = string.format("rg --vimgrep --smart-case --glob='!tags' %s", vim.fn.shellescape(word))
+  elseif vim.fn.executable("git") == 1 and vim.fn.system("git rev-parse --is-inside-work-tree") == "true\n" then
+      cmd = string.format("git grep -n %s -- ':!tags'", vim.fn.shellescape(word))
+      efm = "%f:%l:%m" -- error format for git grep
+  else
+      cmd = string.format("grep -rn --exclude=tags %s .", vim.fn.shellescape(word))
+      efm = "%f:%l:%m" -- error format for grep
+  end
+
+  -- execute command
+  local handle = io.popen(cmd)
+  if not handle then
+      notify("error while executing search command", vim.log.levels.ERROR)
+      return
+  end
+  local result = handle:read("*a")
+  handle:close()
+
+  if result == "" then
+      notify("no matches for '" .. word .. "' found.", vim.log.levels.INFO)
+      return
+  end
+
+  -- split results into lines
+  local lines = vim.split(result, "\n", { trimempty = true })
+
+  -- fill quickfix list
+  vim.fn.setqflist({}, "r", {
+      title = "search for: " .. word,
+      lines = lines,
+      efm = efm,
+  })
+
+  -- open quickfix window
+  vim.cmd("copen")
+  notify(string.format("search for '%s' completed (%d matches).", word, #lines), vim.log.levels.INFO)
+end
+
+M.find = find_to_quickfix
+return M
diff --git a/plugin/quickfix/project-search.lua b/plugin/quickfix/project-search.lua
new file mode 100644 (file)
index 0000000..cfbb6f6
--- /dev/null
@@ -0,0 +1,16 @@
+
+local function project_search()
+    -- get identifier under the cursor
+    local word = vim.fn.expand("<cword>")
+    -- find and put to quickfix
+    require("snippets.find-to-quickfix").find(word)
+end
+
+-- register user command (:ProjectSearch)
+vim.api.nvim_create_user_command("ProjectSearch", project_search, {})
+
+-- create keymap
+vim.keymap.set("n", "<leader>fi", project_search, {
+    desc = "search identifier under cursor in project",
+})
+
diff --git a/plugin/quickfix/search-todos.lua b/plugin/quickfix/search-todos.lua
new file mode 100644 (file)
index 0000000..ace2d91
--- /dev/null
@@ -0,0 +1,15 @@
+
+local function search_todos()
+    local word = "todo"
+    -- find and put to quickfix
+    require("snippets.find-to-quickfix").find(word)
+end
+
+-- register user command (:SearchTodos)
+vim.api.nvim_create_user_command("SearchTodos", search_todos, {})
+
+-- create keymap
+vim.keymap.set("n", "<leader>ft", search_todos, {
+    desc = "search todos in project",
+})
+
diff --git a/plugin/treesitter/project-search.lua b/plugin/treesitter/project-search.lua
deleted file mode 100644 (file)
index 9785104..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-
-local function project_search()
-    -- get identifier under the cursor
-    local word = vim.fn.expand("<cword>")
-    if word == "" then
-        vim.notify("(search-identifier) no identifier under the cursor found", vim.log.levels.WARN)
-        return
-    end
-
-    local cmd
-    local efm = "%f:%l:%c:%m" -- default error format for ripgrep
-
-    -- determine search tool (prio: ripgrep -> git grep -> grep)
-    if vim.fn.executable("rg") == 1 then
-        cmd = string.format("rg --vimgrep --smart-case --glob='!tags' %s", vim.fn.shellescape(word))
-    elseif vim.fn.executable("git") == 1 and vim.fn.system("git rev-parse --is-inside-work-tree") == "true\n" then
-        cmd = string.format("git grep -n %s -- ':!tags'", vim.fn.shellescape(word))
-        efm = "%f:%l:%m" -- error format for git grep
-    else
-        cmd = string.format("grep -rn --exclude=tags %s .", vim.fn.shellescape(word))
-        efm = "%f:%l:%m" -- error format for grep
-    end
-
-    -- execute command
-    local handle = io.popen(cmd)
-    if not handle then
-        vim.notify("(search-identifier) error while executing search command", vim.log.levels.ERROR)
-        return
-    end
-    local result = handle:read("*a")
-    handle:close()
-
-    if result == "" then
-        vim.notify("(search-identifier) no matches for '" .. word .. "' found.", vim.log.levels.INFO)
-        return
-    end
-
-    -- split results into lines
-    local lines = vim.split(result, "\n", { trimempty = true })
-
-    -- fill quickfix list
-    vim.fn.setqflist({}, "r", {
-        title = "search for: " .. word,
-        lines = lines,
-        efm = efm,
-    })
-
-    -- open quickfix window
-    vim.cmd("copen")
-    vim.notify(string.format("search for '%s' completed (%d matches).", word, #lines), vim.log.levels.INFO)
-end
-
--- register user command (:ProjectSearch)
-vim.api.nvim_create_user_command("ProjectSearch", project_search, {})
-
--- Tastenkombination im Normal-Modus: <leader>sw
-vim.keymap.set("n", "<leader>fi", project_search, {
-    desc = "search identifier under cursor in project",
-})
-