mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
feat(picker.actions): added support for action options. Fixes #598
This commit is contained in:
parent
0652591487
commit
8035398e52
2 changed files with 49 additions and 38 deletions
|
@ -5,18 +5,27 @@ local M = {}
|
|||
local SCROLL_WHEEL_DOWN = Snacks.util.keycode("<ScrollWheelDown>")
|
||||
local SCROLL_WHEEL_UP = Snacks.util.keycode("<ScrollWheelUp>")
|
||||
|
||||
function M.jump(picker)
|
||||
---@class snacks.picker.jump.Action: snacks.picker.Action
|
||||
---@field cmd? string
|
||||
|
||||
function M.jump(picker, _, action)
|
||||
---@cast action snacks.picker.jump.Action
|
||||
-- if we're still in insert mode, stop it and schedule
|
||||
-- it to prevent issues with cursor position
|
||||
if vim.fn.mode():sub(1, 1) == "i" then
|
||||
vim.cmd.stopinsert()
|
||||
vim.schedule(function()
|
||||
M.jump(picker)
|
||||
M.jump(picker, _, action)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
picker:close()
|
||||
|
||||
if action.cmd then
|
||||
vim.cmd(action.cmd)
|
||||
end
|
||||
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
|
||||
local current_buf = vim.api.nvim_get_current_buf()
|
||||
|
@ -92,10 +101,12 @@ function M.jump(picker)
|
|||
end
|
||||
end
|
||||
|
||||
M.cancel = function() end
|
||||
|
||||
M.cancel = "close"
|
||||
M.edit = M.jump
|
||||
M.confirm = M.jump
|
||||
M.edit_split = { action = "jump", cmd = "split" }
|
||||
M.edit_vsplit = { action = "jump", cmd = "vsplit" }
|
||||
M.edit_tab = { action = "jump", cmd = "tabnew" }
|
||||
|
||||
function M.toggle_maximize(picker)
|
||||
picker.layout:maximize()
|
||||
|
@ -189,24 +200,6 @@ function M.history_forward(picker)
|
|||
picker:hist(true)
|
||||
end
|
||||
|
||||
function M.edit_tab(picker)
|
||||
picker:close()
|
||||
vim.cmd("tabnew")
|
||||
return picker:action("edit")
|
||||
end
|
||||
|
||||
function M.edit_split(picker)
|
||||
picker:close()
|
||||
vim.cmd("split")
|
||||
return picker:action("edit")
|
||||
end
|
||||
|
||||
function M.edit_vsplit(picker)
|
||||
picker:close()
|
||||
vim.cmd("vsplit")
|
||||
return picker:action("edit")
|
||||
end
|
||||
|
||||
--- Toggles the selection of the current item,
|
||||
--- and moves the cursor to the next item.
|
||||
function M.select_and_next(picker)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
local M = {}
|
||||
|
||||
---@alias snacks.picker.Action.fn fun(self: snacks.Picker, item?:snacks.picker.Item):(boolean|string?)
|
||||
---@alias snacks.picker.Action.spec.one string|snacks.picker.Action|snacks.picker.Action.fn
|
||||
---@alias snacks.picker.Action.fn fun(self: snacks.Picker, item?:snacks.picker.Item, action?:snacks.picker.Action):(boolean|string?)
|
||||
---@alias snacks.picker.Action.spec.one string|snacks.picker.Action|snacks.picker.Action.fn|{action?:snacks.picker.Action.spec.one}
|
||||
---@alias snacks.picker.Action.spec snacks.picker.Action.spec.one|snacks.picker.Action.spec.one[]
|
||||
|
||||
---@class snacks.picker.Action
|
||||
---@field action snacks.picker.Action.fn
|
||||
---@field desc? string
|
||||
---@field name? string
|
||||
|
||||
---@param picker snacks.Picker
|
||||
function M.get(picker)
|
||||
|
@ -24,7 +25,7 @@ function M.get(picker)
|
|||
if not p then
|
||||
return
|
||||
end
|
||||
t[k] = M.resolve(k, p, k) or false
|
||||
t[k] = M.wrap(k, p, k) or false
|
||||
return rawget(t, k)
|
||||
end,
|
||||
})
|
||||
|
@ -34,17 +35,33 @@ end
|
|||
---@param action snacks.picker.Action.spec
|
||||
---@param picker snacks.Picker
|
||||
---@param name? string
|
||||
---@return snacks.picker.Action?
|
||||
---@return snacks.win.Action?
|
||||
function M.wrap(action, picker, name)
|
||||
action = M.resolve(action, picker, name)
|
||||
action.name = name
|
||||
return {
|
||||
name = name,
|
||||
action = function()
|
||||
action.action(picker, picker:current(), action)
|
||||
end,
|
||||
desc = action.desc,
|
||||
}
|
||||
end
|
||||
|
||||
---@param action snacks.picker.Action.spec
|
||||
---@param picker snacks.Picker
|
||||
---@param name? string
|
||||
---@return snacks.picker.Action
|
||||
function M.resolve(action, picker, name)
|
||||
if not action then
|
||||
assert(name, "Missing action without name")
|
||||
local fn, desc = picker.input.win[name], name
|
||||
return {
|
||||
action = function()
|
||||
action = function(p)
|
||||
if not fn then
|
||||
return name
|
||||
end
|
||||
fn(picker.input.win)
|
||||
fn(p.input.win)
|
||||
end,
|
||||
desc = desc,
|
||||
}
|
||||
|
@ -60,9 +77,9 @@ function M.resolve(action, picker, name)
|
|||
return M.resolve(a, picker)
|
||||
end, action)
|
||||
return {
|
||||
action = function(_, item)
|
||||
action = function(p, i, aa)
|
||||
for _, a in ipairs(actions) do
|
||||
a.action(picker, item)
|
||||
a.action(p, i, aa)
|
||||
end
|
||||
end,
|
||||
desc = table.concat(
|
||||
|
@ -72,17 +89,18 @@ function M.resolve(action, picker, name)
|
|||
", "
|
||||
),
|
||||
}
|
||||
elseif type(action) == "table" then
|
||||
if type(action.action) ~= "function" then
|
||||
action = vim.deepcopy(action)
|
||||
action.action = M.resolve(action.action, picker).action
|
||||
end
|
||||
---@cast action snacks.picker.Action
|
||||
return action
|
||||
end
|
||||
action = type(action) == "function" and {
|
||||
assert(type(action) == "function", "Invalid action")
|
||||
return {
|
||||
action = action,
|
||||
desc = name or nil,
|
||||
} or action
|
||||
---@cast action snacks.picker.Action
|
||||
return {
|
||||
action = function()
|
||||
return action.action(picker, picker:current())
|
||||
end,
|
||||
desc = action.desc,
|
||||
}
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue