refactor(picker): ctx:clone. closes #2386

This commit is contained in:
Folke Lemaitre 2025-10-29 23:54:50 +01:00
parent 5eea5f9428
commit 5f429fa58f
No known key found for this signature in database
GPG key ID: 9B52594D560070AB
4 changed files with 31 additions and 22 deletions

View file

@ -11,7 +11,7 @@ local M = {}
---@alias snacks.picker.Pos {[1]:number, [2]:number}
---@alias snacks.picker.toggle {icon?:string, enabled?:boolean, value?:boolean}
--- Generic filter used by finders to pre-filter items
--- Generic filter used by some finders to pre-filter items
---@class snacks.picker.filter.Config
---@field cwd? boolean|string only show files for the given cwd
---@field buf? boolean|number only show items for the current or given buffer
@ -75,6 +75,7 @@ local M = {}
---@field limit? number when set, the finder will stop after finding this number of items. useful for live searches
---@field limit_live? number when set, the finder will stop after finding this number of items during live searches. useful for performance
---@field ui_select? boolean set `vim.ui.select` to a snacks picker
---@field filter? snacks.picker.filter.Config generic filter used by some finders
--- Source definition
---@field items? snacks.picker.finder.Item[] items to show instead of using a finder
---@field format? string|snacks.picker.format|string format function or preset

View file

@ -146,9 +146,8 @@ function M.multi(opts)
end
local finder = M.finder(source.finder)
finders[#finders + 1] = function(fopts, ctx)
fopts = Snacks.config.merge({}, vim.deepcopy(source), fopts)
ctx = setmetatable({}, { __index = ctx })
ctx._opts = fopts
fopts = Snacks.config.merge(vim.deepcopy(source), fopts)
ctx = ctx:clone(fopts)
-- Update source filter when needed
if not vim.tbl_isempty(fopts.filter or {}) then
ctx.filter = ctx.filter:clone():init(fopts)

View file

@ -14,8 +14,6 @@
local M = {}
M.__index = M
local uv = vim.uv or vim.loop
---@param picker snacks.Picker
function M.new(picker)
local opts = picker.opts ---@type snacks.picker.Config|{filter?:snacks.picker.filter.Config}

View file

@ -17,12 +17,36 @@ M.__index = M
local Ctx = {}
Ctx.__index = Ctx
---@param picker snacks.Picker
---@param filter snacks.picker.Filter
function Ctx.new(picker, filter)
local notified = false
local self = setmetatable({}, Ctx)
self.picker = picker
self.filter = filter
self.meta = {}
self.async = setmetatable({}, {
__index = function()
if not notified then
notified = true
Snacks.notify.warn("You can only use the `async` object in async functions")
end
end,
})
return self
end
---@param opts? snacks.picker.Config
---@return snacks.picker.finder.ctx
function Ctx:clone(opts)
return setmetatable({ _opts = opts }, { __index = self })
end
---@generic T: snacks.picker.Config
---@param opts T
---@return T
function Ctx:opts(opts)
self._opts = self._opts or vim.deepcopy(self.picker.opts)
self._opts = Snacks.config.merge(self._opts, opts)
self._opts = setmetatable(opts or {}, { __index = self._opts or self.picker.opts })
return self._opts
end
@ -72,20 +96,7 @@ end
---@param picker snacks.Picker
function M:ctx(picker)
local notified = false
local ret = setmetatable({}, Ctx)
ret.picker = picker
ret.filter = self.filter
ret.meta = {}
ret.async = setmetatable({}, {
__index = function()
if not notified then
notified = true
Snacks.notify.warn("You can only use the `async` object in async functions")
end
end,
})
return ret
return Ctx.new(picker, self.filter)
end
---@param filter snacks.picker.Filter