feat(picker.finder): optional transform function

This commit is contained in:
Folke Lemaitre 2025-01-22 23:47:41 +01:00
parent 9c0e2d4362
commit 5e69fb83d5
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
3 changed files with 34 additions and 0 deletions

View file

@ -73,6 +73,7 @@ local M = {}
---@field preview? snacks.picker.preview|string preview function or preset
---@field matcher? snacks.picker.matcher.Config matcher config
---@field sort? snacks.picker.sort|snacks.picker.sort.Config sort function or config
---@field transform? string|snacks.picker.transform transform/filter function
--- UI
---@field win? snacks.picker.win.Config
---@field layout? snacks.picker.layout.Config|string|{}|fun(source:string):(snacks.picker.layout.Config|string)

View file

@ -12,6 +12,7 @@ M.__index = M
---@field picker snacks.Picker
---@field filter snacks.picker.Filter
---@field async snacks.picker.Async
---@field meta table<string, any>
---@alias snacks.picker.finder.async fun(cb:async fun(item:snacks.picker.finder.Item))
---@alias snacks.picker.finder.result snacks.picker.finder.Item[] | snacks.picker.finder.async
@ -64,6 +65,7 @@ function M:ctx(picker)
end,
}),
filter = self.filter,
meta = {},
}
setmetatable(ret, { __index = M:deprecated(self.filter) })
return ret
@ -119,6 +121,19 @@ function M:run(picker)
self.items[item.idx] = item
end
if picker.opts.transform then
local transform = Snacks.picker.config.transform(picker.opts)
---@param item snacks.picker.finder.Item
function add(item)
local t = transform(item, ctx)
item = type(t) == "table" and t or item
if t ~= false then
item.idx, item.score = #self.items + 1, default_score
self.items[item.idx] = item
end
end
end
-- PERF: if finder is a table, we can skip the async part
if type(finder) == "table" then
local items = finder --[[@as snacks.picker.finder.Item[] ]]

View file

@ -0,0 +1,18 @@
---@class snacks.picker.transformers
---@field [string] snacks.picker.transform
local M = {}
function M.unique_file(item, ctx)
ctx.meta.done = ctx.meta.done or {} ---@type table<string, boolean>
local path = Snacks.picker.util.path(item)
if not path or ctx.meta.done[path] then
return false
end
ctx.meta.done[path] = true
end
function M.text_to_file(item, ctx)
item.file = item.file or item.text
end
return M