mirror of
https://github.com/folke/snacks.nvim
synced 2025-12-23 08:47:57 +00:00
Refactored picker resume functionality to support multiple picker states instead of just the last one. Each picker source now maintains its own resume state, allowing users to resume any previously opened picker.
Key improvements:
- Multi-state storage: Each picker source tracks its own state independently
- Flexible API: `Snacks.picker.resume({ source = "files" })` or with include/exclude options
- LSP caching: Cache LSP results for instant resume of LSP pickers
- Better UX: Can resume specific pickers by source name
Moved resume logic to dedicated `picker/resume.lua` module for better separation of concerns.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
3.1 KiB
Lua
117 lines
3.1 KiB
Lua
---@class snacks.picker
|
|
---@field actions snacks.picker.actions
|
|
---@field config snacks.picker.config
|
|
---@field format snacks.picker.formatters
|
|
---@field preview snacks.picker.previewers
|
|
---@field sort snacks.picker.sorters
|
|
---@field util snacks.picker.util
|
|
---@field current? snacks.Picker
|
|
---@field highlight snacks.picker.highlight
|
|
---@field resume fun(opts?: snacks.picker.Config):snacks.Picker
|
|
---@field sources snacks.picker.sources.Config
|
|
---@overload fun(opts: snacks.picker.Config): snacks.Picker
|
|
---@overload fun(source: string, opts: snacks.picker.Config): snacks.Picker
|
|
local M = setmetatable({}, {
|
|
__call = function(M, ...)
|
|
return M.pick(...)
|
|
end,
|
|
---@param M snacks.picker
|
|
__index = function(M, k)
|
|
if type(k) ~= "string" then
|
|
return
|
|
end
|
|
local mods = {
|
|
"actions",
|
|
"config",
|
|
"format",
|
|
"preview",
|
|
"util",
|
|
"sort",
|
|
highlight = "util.highlight",
|
|
sources = "config.sources",
|
|
}
|
|
for m, mod in pairs(mods) do
|
|
mod = mod == k and k or m == k and mod or nil
|
|
if mod then
|
|
---@diagnostic disable-next-line: no-unknown
|
|
M[k] = require("snacks.picker." .. mod)
|
|
return rawget(M, k)
|
|
end
|
|
end
|
|
return M.config.wrap(k, { check = true })
|
|
end,
|
|
})
|
|
|
|
---@type snacks.meta.Meta
|
|
M.meta = {
|
|
desc = "Picker for selecting items",
|
|
needs_setup = true,
|
|
merge = { config = "config.defaults", picker = "core.picker", "actions" },
|
|
}
|
|
|
|
---@class snacks.picker.resume.Opts
|
|
---@field source? string
|
|
---@field include? string[]
|
|
---@field exclude? string[]
|
|
|
|
-- create actual picker functions for autocomplete
|
|
vim.defer_fn(function()
|
|
M.config.setup()
|
|
end, 10)
|
|
|
|
--- Create a new picker
|
|
---@param source? string
|
|
---@param opts? snacks.picker.Config
|
|
---@overload fun(opts: snacks.picker.Config): snacks.Picker
|
|
function M.pick(source, opts)
|
|
if not opts and type(source) == "table" then
|
|
opts, source = source, nil
|
|
end
|
|
opts = opts or {}
|
|
opts.source = source or opts.source
|
|
-- Show pickers if no source, items or finder is provided
|
|
if not (opts.source or opts.items or opts.finder or opts.multi) then
|
|
opts.source = "pickers"
|
|
return M.pick(opts)
|
|
end
|
|
local current = opts.source and M.get({ source = opts.source })[1]
|
|
if current then
|
|
current:close()
|
|
return
|
|
end
|
|
return require("snacks.picker.core.picker").new(opts)
|
|
end
|
|
|
|
--- Implementation for `vim.ui.select`
|
|
---@type snacks.picker.ui_select
|
|
function M.select(...)
|
|
return require("snacks.picker.select").select(...)
|
|
end
|
|
|
|
---@private
|
|
function M.setup()
|
|
if M.config.get().ui_select then
|
|
vim.ui.select = M.select
|
|
end
|
|
end
|
|
|
|
---@private
|
|
function M.health()
|
|
require("snacks.picker.core._health").health()
|
|
end
|
|
|
|
--- Get active pickers, optionally filtered by source,
|
|
--- or the current tab
|
|
---@param opts? {source?: string, tab?: boolean} tab defaults to true
|
|
function M.get(opts)
|
|
return require("snacks.picker.core.picker").get(opts)
|
|
end
|
|
|
|
---@param opts? snacks.picker.resume.Opts
|
|
---@overload fun(source:string):snacks.Picker?
|
|
---@return snacks.Picker?
|
|
function M.resume(opts)
|
|
return require("snacks.picker.resume").resume(opts)
|
|
end
|
|
|
|
return M
|