feat(picker.lines): jump to first position of match. Closes #806

This commit is contained in:
Folke Lemaitre 2025-01-31 14:13:35 +01:00
parent 56db8f14bf
commit ae897f329f
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
4 changed files with 22 additions and 2 deletions

View file

@ -83,8 +83,12 @@ function M.jump(picker, _, action)
vim.api.nvim_win_set_buf(win, buf)
-- set the cursor
if item.pos and item.pos[1] > 0 then
vim.api.nvim_win_set_cursor(win, { item.pos[1], item.pos[2] })
local pos = item.pos
if picker.opts.jump.match then
pos = picker.matcher:bufpos(buf, item) or pos
end
if pos and pos[1] > 0 then
vim.api.nvim_win_set_cursor(win, { pos[1], pos[2] })
elseif item.search then
vim.cmd(item.search)
vim.cmd("noh")

View file

@ -169,6 +169,7 @@ local defaults = {
tagstack = false, -- save the current position in the tagstack
reuse_win = false, -- reuse an existing window if the buffer is already open
close = true, -- close the picker when jumping/editing to a location (defaults to true)
match = false, -- jump to the first match position. (useful for `lines`)
},
toggles = {
follow = "f",

View file

@ -388,6 +388,7 @@ M.lines = {
preview = "main",
preset = "ivy",
},
jump = { match = true },
-- allow any window to be used as the main window
main = { current = true },
---@param picker snacks.Picker

View file

@ -388,6 +388,20 @@ function M:positions(item)
return ret
end
--- Returns the column of the first position of the matched pattern in the item.
---@param buf number
---@param item snacks.picker.Item
---@return snacks.picker.Pos?
function M:bufpos(buf, item)
if not item.pos then
return
end
local line = vim.api.nvim_buf_get_lines(buf, item.pos[1] - 1, item.pos[1], false)[1] or ""
local positions = self:positions({ text = line, idx = 1, score = 0 }).text or {}
table.sort(positions)
return #positions > 0 and { item.pos[1], positions[1] - 1 } or nil
end
---@param str string
---@param pattern string[]
---@param from number