mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
feat(picker): pin picker as a split to left/bottom/top/right with ctrl+z+(hjkl)
This commit is contained in:
parent
eac06ed1a5
commit
27cba535a6
4 changed files with 57 additions and 4 deletions
|
@ -5,6 +5,9 @@ local M = {}
|
|||
---@class snacks.picker.jump.Action: snacks.picker.Action
|
||||
---@field cmd? snacks.picker.EditCmd
|
||||
|
||||
---@class snacks.picker.layout.Action: snacks.picker.Action
|
||||
---@field layout? snacks.picker.layout.Config|string
|
||||
|
||||
---@enum (key) snacks.picker.EditCmd
|
||||
local edit_cmd = {
|
||||
edit = "buffer",
|
||||
|
@ -155,6 +158,27 @@ M.edit_split = M.split
|
|||
M.edit_vsplit = M.vsplit
|
||||
M.edit_tab = M.tab
|
||||
|
||||
function M.layout(picker, _, action)
|
||||
---@cast action snacks.picker.layout.Action
|
||||
assert(action.layout, "Layout action requires a layout")
|
||||
local opts = type(action.layout) == "table" and { layout = action.layout } or action.layout
|
||||
---@cast opts snacks.picker.Config
|
||||
local layout = Snacks.picker.config.layout(opts)
|
||||
picker:set_layout(layout)
|
||||
-- Adjust some options for split layouts
|
||||
if (layout.layout.position or "float") ~= "float" then
|
||||
picker.opts.auto_close = false
|
||||
picker.opts.jump.close = false
|
||||
picker:toggle_preview(false)
|
||||
picker.list.win:focus()
|
||||
end
|
||||
end
|
||||
|
||||
M.layout_top = { action = "layout", layout = "top" }
|
||||
M.layout_bottom = { action = "layout", layout = "bottom" }
|
||||
M.layout_left = { action = "layout", layout = "left" }
|
||||
M.layout_right = { action = "layout", layout = "right" }
|
||||
|
||||
function M.toggle_maximize(picker)
|
||||
picker.layout:maximize()
|
||||
end
|
||||
|
|
|
@ -219,6 +219,14 @@ local defaults = {
|
|||
["<c-s>"] = { "edit_split", mode = { "i", "n" } },
|
||||
["<c-u>"] = { "list_scroll_up", mode = { "i", "n" } },
|
||||
["<c-v>"] = { "edit_vsplit", mode = { "i", "n" } },
|
||||
["<c-z>h"] = { "layout_left", mode = { "i", "n" } },
|
||||
["<c-z><c-h>"] = { "layout_left", mode = { "i", "n" } },
|
||||
["<c-z>j"] = { "layout_bottom", mode = { "i", "n" } },
|
||||
["<c-z><c-j>"] = { "layout_bottom", mode = { "i", "n" } },
|
||||
["<c-z>k"] = { "layout_top", mode = { "i", "n" } },
|
||||
["<c-z><c-k>"] = { "layout_top", mode = { "i", "n" } },
|
||||
["<c-z>l"] = { "layout_right", mode = { "i", "n" } },
|
||||
["<c-z><c-l>"] = { "layout_right", mode = { "i", "n" } },
|
||||
["?"] = "toggle_help_input",
|
||||
["G"] = "list_bottom",
|
||||
["gg"] = "list_top",
|
||||
|
@ -260,6 +268,14 @@ local defaults = {
|
|||
["<c-s>"] = "edit_split",
|
||||
["<c-u>"] = "list_scroll_up",
|
||||
["<c-v>"] = "edit_vsplit",
|
||||
["<c-z>h"] = { "layout_left", mode = { "i", "n" } },
|
||||
["<c-z><c-h>"] = { "layout_left", mode = { "i", "n" } },
|
||||
["<c-z>j"] = { "layout_bottom", mode = { "i", "n" } },
|
||||
["<c-z><c-j>"] = { "layout_bottom", mode = { "i", "n" } },
|
||||
["<c-z>k"] = { "layout_top", mode = { "i", "n" } },
|
||||
["<c-z><c-k>"] = { "layout_top", mode = { "i", "n" } },
|
||||
["<c-z>l"] = { "layout_right", mode = { "i", "n" } },
|
||||
["<c-z><c-l>"] = { "layout_right", mode = { "i", "n" } },
|
||||
["?"] = "toggle_help_list",
|
||||
["G"] = "list_bottom",
|
||||
["gg"] = "list_top",
|
||||
|
|
|
@ -209,12 +209,20 @@ function M.layout(opts)
|
|||
end
|
||||
|
||||
-- Resolve the preset
|
||||
local preset = M.resolve(layout.preset or "custom", opts.source)
|
||||
---@type snacks.picker.layout.Config
|
||||
local ret = vim.deepcopy(opts.layouts and opts.layouts[preset] or {})
|
||||
local layouts = opts.layouts or M.get().layouts or {}
|
||||
local done = {} ---@type table<string, boolean>
|
||||
local todo = { layout } ---@type snacks.picker.layout.Config[]
|
||||
while true do
|
||||
local preset = M.resolve(todo[1].preset or "custom", opts.source)
|
||||
if not preset or done[preset] or not layouts[preset] then
|
||||
break
|
||||
end
|
||||
done[preset] = true
|
||||
table.insert(todo, 1, vim.deepcopy(layouts[preset]))
|
||||
end
|
||||
|
||||
-- Merge and return the layout
|
||||
return Snacks.config.merge(ret, layout)
|
||||
return Snacks.config.merge(unpack(todo))
|
||||
end
|
||||
|
||||
---@generic T
|
||||
|
|
|
@ -175,4 +175,9 @@ M.vscode = {
|
|||
},
|
||||
}
|
||||
|
||||
M.left = M.sidebar
|
||||
M.right = { preset = "sidebar", layout = { position = "right" } }
|
||||
M.top = { preset = "ivy", layout = { position = "top" } }
|
||||
M.bottom = { preset = "ivy", layout = { position = "bottom" } }
|
||||
|
||||
return M
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue