diff --git a/lua/snacks/picker/config/defaults.lua b/lua/snacks/picker/config/defaults.lua index d60ea111..60d1d4e3 100644 --- a/lua/snacks/picker/config/defaults.lua +++ b/lua/snacks/picker/config/defaults.lua @@ -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 diff --git a/lua/snacks/picker/config/init.lua b/lua/snacks/picker/config/init.lua index d39e3fd7..969c7625 100644 --- a/lua/snacks/picker/config/init.lua +++ b/lua/snacks/picker/config/init.lua @@ -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) diff --git a/lua/snacks/picker/core/filter.lua b/lua/snacks/picker/core/filter.lua index 884923ea..6e924c87 100644 --- a/lua/snacks/picker/core/filter.lua +++ b/lua/snacks/picker/core/filter.lua @@ -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} diff --git a/lua/snacks/picker/core/finder.lua b/lua/snacks/picker/core/finder.lua index 183f6d8f..79eb4a84 100644 --- a/lua/snacks/picker/core/finder.lua +++ b/lua/snacks/picker/core/finder.lua @@ -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