feat(picker): beter API to interact with active pickers. Closes #851

This commit is contained in:
Folke Lemaitre 2025-02-01 14:39:24 +01:00
parent 50834bbf43
commit 6a8337396a
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
3 changed files with 26 additions and 7 deletions

View file

@ -18,6 +18,7 @@ local defaults = {
replace_netrw = true, -- Replace netrw with the snacks explorer
}
---@private
---@param event? vim.api.keyset.create_autocmd.callback_args
function M.setup(event)
local opts = Snacks.config.get("explorer", defaults)

View file

@ -66,6 +66,21 @@ function M:__newindex(key, value)
end
end
---@param opts? {source?: string}
function M.get(opts)
opts = opts or {}
local ret = {} ---@type snacks.Picker[]
for picker in pairs(M._active) do
if not opts.source or picker.opts.source == opts.source then
ret[#ret + 1] = picker
end
end
table.sort(ret, function(a, b)
return a.id < b.id
end)
return ret
end
---@hide
---@param opts? snacks.picker.Config
---@return snacks.Picker
@ -129,7 +144,6 @@ function M.new(opts)
self.visual = Snacks.picker.util.visual()
self.start_time = uv.hrtime()
Snacks.picker.current = self
self._main = require("snacks.picker.core.main").new(self.opts.main)
local actions = require("snacks.picker.core.actions").get(self)
self.opts.win.input.actions = actions
@ -592,7 +606,7 @@ function M:close()
M.last.topline = self.list.top
M.last.opts = M.last.opts or {}
M.last.opts.live = self.opts.live
Snacks.picker.current = nil
local current = vim.api.nvim_get_current_win()
local is_picker_win = vim.tbl_contains({ self.input.win.win, self.list.win.win, self.preview.win.win }, current)
if is_picker_win and vim.api.nvim_win_is_valid(self.main) then

View file

@ -17,9 +17,6 @@ local M = setmetatable({}, {
end,
---@param M snacks.picker
__index = function(M, k)
if k == "current" then
return nil
end
if type(k) ~= "string" then
return
end
@ -72,8 +69,9 @@ function M.pick(source, opts)
opts.source = "pickers"
return M.pick(opts)
end
if opts.source and M.current and M.current.opts.source == opts.source then
M.current:close()
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)
@ -97,4 +95,10 @@ function M.health()
require("snacks.picker.core._health").health()
end
--- Get active pickers, optionally filtered by source
---@param opts? {source?: string}
function M.get(opts)
return require("snacks.picker.core.picker").get(opts)
end
return M