From 57fbda70d66d808c10974448d4003f567b78e784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20F=2E=20Bortl=C3=ADk?= Date: Wed, 22 Oct 2025 06:33:33 +0200 Subject: [PATCH] feat(picker): allow configuring pathspec for git grep (#2311) ## Description This is in place of the rejected PR #2178. Please consider the following reasons for merging. This PR adds the possibility to specify pathspec patterns to the `git grep .... -- ` command. This is necessary for ignoring large git-tracked files (that cannot be added to `.gitignore`) from the git grep search. git-grepping in some large files with very long lines can freeze Neovim and make `Snacks.picker.git_grep` completely unusable. Without this change the picker cannot be configured to use some pathspecs by default. They can be added dynamically in live mode but re-typing the same pathspecs every time one needs to use `Snacks.picker.git_grep` would be silly. In reply to the [question if cmd_args can be used for this](https://github.com/folke/snacks.nvim/pull/2178#discussion_r2448762906): No. The "pathspecs" need to be specified *last* (optionally after `--`). When configuring Snacks.picker like this: ```lua sources = { git_grep = { cmd_args = { ':!*.min.js', ':!*.min.css', ':!uv.lock' }, }, } ``` then the `cmd_args` are inserted in front of the search pattern and `git grep` doesn't find anything. The following config can't be used either because that will cause the [search pattern](https://github.com/folke/snacks.nvim/blob/c9fa6f7b0724587d4c4974817aad96d93f469437/lua/snacks/picker/source/git.lua#L76) to be treated as one of the pathspecs. ```lua git_grep = { cmd_args = { '--', ':!*.min.js', ':!*.min.css', ':!uv.lock' }, }, ``` --- lua/snacks/picker/config/sources.lua | 1 + lua/snacks/picker/source/git.lua | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lua/snacks/picker/config/sources.lua b/lua/snacks/picker/config/sources.lua index 37164fc0..59f851a5 100644 --- a/lua/snacks/picker/config/sources.lua +++ b/lua/snacks/picker/config/sources.lua @@ -260,6 +260,7 @@ M.git_files = { ---@field untracked? boolean search in untracked files ---@field submodules? boolean search in submodule files ---@field need_search? boolean require a search pattern +---@field pathspec? string|string[] pathspec pattern(s) ---@field ignorecase? boolean ignore case M.git_grep = { finder = "git_grep", diff --git a/lua/snacks/picker/source/git.lua b/lua/snacks/picker/source/git.lua index 42e8bb57..587a5554 100644 --- a/lua/snacks/picker/source/git.lua +++ b/lua/snacks/picker/source/git.lua @@ -73,7 +73,17 @@ function M.grep(opts, ctx) if opts.ignorecase then table.insert(args, "-i") end - table.insert(args, ctx.filter.search) + + local pattern, pargs = Snacks.picker.util.parse(ctx.filter.search) + table.insert(args, pattern) + + args[#args + 1] = "--" + vim.list_extend(args, pargs) + + local pathspec = type(opts.pathspec) == "table" and opts.pathspec or { opts.pathspec } + ---@cast pathspec string[] + vim.list_extend(args, pathspec) + if not opts.cwd then opts.cwd = Snacks.git.get_root() or uv.cwd() or "." ctx.picker:set_cwd(opts.cwd)