feat(picker.proc): finder to process json

This commit is contained in:
Folke Lemaitre 2025-10-26 11:50:32 +01:00
parent 1f194746d7
commit 5294c4f39e
No known key found for this signature in database
GPG key ID: 9B52594D560070AB

View file

@ -14,16 +14,24 @@ M.USE_QUEUE = true
---@field cwd? string
---@field notify? boolean Notify on failure
---@field transform? snacks.picker.transform
---@field raw? boolean Return raw output without processing
---@param opts snacks.picker.proc.Config|{[1]: snacks.picker.Config, [2]: snacks.picker.proc.Config}
---@type snacks.picker.finder
function M.proc(opts, ctx)
local function get_opts(opts)
if svim.islist(opts) then
local transform = opts[2].transform
opts = Snacks.config.merge(unpack(vim.deepcopy(opts))) --[[@as snacks.picker.proc.Config]]
opts.transform = transform
end
---@cast opts snacks.picker.proc.Config
return opts
end
---@param opts snacks.picker.proc.Config|{[1]: snacks.picker.Config, [2]: snacks.picker.proc.Config}
---@type snacks.picker.finder
function M.proc(opts, ctx)
opts = get_opts(opts)
---@cast opts snacks.picker.proc.Config
assert(opts.cmd, "`opts.cmd` is required")
---@async
return function(cb)
@ -102,6 +110,9 @@ function M.proc(opts, ctx)
if not data then
return prev and cb({ text = prev })
end
if opts.raw then
return cb({ text = data })
end
local from = 1
while from <= #data do
local nl = data:find(sep, from, true)
@ -152,6 +163,34 @@ function M.proc(opts, ctx)
end
end
---@param opts snacks.picker.proc.Config|{[1]: snacks.picker.Config, [2]: snacks.picker.proc.Config}
---@type snacks.picker.finder
function M.json(opts, ctx)
opts = get_opts(opts) --[[@as snacks.picker.proc.Config]]
opts.raw = true
local transform = opts.transform
opts.transform = nil
return function(cb)
local Buffer = require("string.buffer")
local data = Buffer.new()
M.proc(opts, ctx)(function(item)
data:put(item.text)
end)
local json = vim.json.decode(data:get())
assert(svim.islist(json), "Expected JSON array")
---@cast json snacks.picker.finder.Item[]
for _, item in ipairs(json) do
item = setmetatable({ item = item }, { __index = item })
item.text = item.text or ""
local t = transform and transform(item, ctx) or nil
item = type(t) == "table" and t or item
if t ~= false then
cb(item)
end
end
end
end
---@param opts {cmd: string, args?: string[], cwd?: string}
function M.debug(opts)
vim.schedule(function()