mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 19:28:24 +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
|
---@class snacks.picker.jump.Action: snacks.picker.Action
|
||||||
---@field cmd? snacks.picker.EditCmd
|
---@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
|
---@enum (key) snacks.picker.EditCmd
|
||||||
local edit_cmd = {
|
local edit_cmd = {
|
||||||
edit = "buffer",
|
edit = "buffer",
|
||||||
|
@ -155,6 +158,27 @@ M.edit_split = M.split
|
||||||
M.edit_vsplit = M.vsplit
|
M.edit_vsplit = M.vsplit
|
||||||
M.edit_tab = M.tab
|
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)
|
function M.toggle_maximize(picker)
|
||||||
picker.layout:maximize()
|
picker.layout:maximize()
|
||||||
end
|
end
|
||||||
|
|
|
@ -219,6 +219,14 @@ local defaults = {
|
||||||
["<c-s>"] = { "edit_split", mode = { "i", "n" } },
|
["<c-s>"] = { "edit_split", mode = { "i", "n" } },
|
||||||
["<c-u>"] = { "list_scroll_up", mode = { "i", "n" } },
|
["<c-u>"] = { "list_scroll_up", mode = { "i", "n" } },
|
||||||
["<c-v>"] = { "edit_vsplit", 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",
|
["?"] = "toggle_help_input",
|
||||||
["G"] = "list_bottom",
|
["G"] = "list_bottom",
|
||||||
["gg"] = "list_top",
|
["gg"] = "list_top",
|
||||||
|
@ -260,6 +268,14 @@ local defaults = {
|
||||||
["<c-s>"] = "edit_split",
|
["<c-s>"] = "edit_split",
|
||||||
["<c-u>"] = "list_scroll_up",
|
["<c-u>"] = "list_scroll_up",
|
||||||
["<c-v>"] = "edit_vsplit",
|
["<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",
|
["?"] = "toggle_help_list",
|
||||||
["G"] = "list_bottom",
|
["G"] = "list_bottom",
|
||||||
["gg"] = "list_top",
|
["gg"] = "list_top",
|
||||||
|
|
|
@ -209,12 +209,20 @@ function M.layout(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Resolve the preset
|
-- Resolve the preset
|
||||||
local preset = M.resolve(layout.preset or "custom", opts.source)
|
local layouts = opts.layouts or M.get().layouts or {}
|
||||||
---@type snacks.picker.layout.Config
|
local done = {} ---@type table<string, boolean>
|
||||||
local ret = vim.deepcopy(opts.layouts and opts.layouts[preset] or {})
|
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
|
-- Merge and return the layout
|
||||||
return Snacks.config.merge(ret, layout)
|
return Snacks.config.merge(unpack(todo))
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic T
|
---@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
|
return M
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue