mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 10:49:08 +00:00
feat(picker): allow showing the preview in the main buffer
This commit is contained in:
parent
235c8cb683
commit
deeacf77c0
5 changed files with 65 additions and 13 deletions
|
@ -44,7 +44,7 @@ local M = {}
|
|||
---@field reverse? boolean when true, the list will be reversed (bottom-up)
|
||||
---@field fullscreen? boolean open in fullscreen
|
||||
---@field cycle? boolean cycle through the list
|
||||
---@field preview? boolean show preview window
|
||||
---@field preview? boolean|"main" show preview window in the picker or the main window
|
||||
---@field preset? string|fun(source:string):string
|
||||
|
||||
---@class snacks.picker.win.Config
|
||||
|
|
|
@ -17,6 +17,9 @@ function M.get(picker)
|
|||
---@param t table<string, snacks.win.Action>
|
||||
---@param k string
|
||||
__index = function(t, k)
|
||||
if type(k) ~= "string" then
|
||||
return
|
||||
end
|
||||
local p = ref()
|
||||
if not p then
|
||||
return
|
||||
|
|
|
@ -82,9 +82,11 @@ function M.new(opts)
|
|||
M._pickers[self] = true
|
||||
M._active[self] = true
|
||||
|
||||
local layout = Snacks.picker.config.layout(self.opts)
|
||||
self.list = require("snacks.picker.core.list").new(self)
|
||||
self.input = require("snacks.picker.core.input").new(self)
|
||||
self.preview = require("snacks.picker.core.preview").new(self.opts)
|
||||
self.preview =
|
||||
require("snacks.picker.core.preview").new(self.opts, layout.preview == "main" and self.parent_win or nil)
|
||||
|
||||
M.last = {
|
||||
opts = self.opts,
|
||||
|
@ -109,11 +111,10 @@ function M.new(opts)
|
|||
end
|
||||
end)
|
||||
|
||||
self:init_layout()
|
||||
self:init_layout(layout)
|
||||
self.input.win:on("VimResized", function()
|
||||
vim.schedule(function()
|
||||
local layout = Snacks.picker.config.layout(self.opts)
|
||||
self:set_layout(layout)
|
||||
self:set_layout(Snacks.picker.config.layout(self.opts))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@ -132,6 +133,12 @@ function M:init_layout(layout)
|
|||
layout = layout or Snacks.picker.config.layout(self.opts)
|
||||
self.resolved_layout = vim.deepcopy(layout)
|
||||
local opts = layout --[[@as snacks.layout.Config]]
|
||||
local preview_main = layout.preview == "main"
|
||||
local preview_hidden = layout.preview == false or preview_main
|
||||
local backdrop = nil
|
||||
if preview_main then
|
||||
backdrop = false
|
||||
end
|
||||
self.layout = Snacks.layout.new(vim.tbl_deep_extend("force", opts, {
|
||||
win = {
|
||||
wo = {
|
||||
|
@ -141,13 +148,17 @@ function M:init_layout(layout)
|
|||
wins = {
|
||||
input = self.input.win,
|
||||
list = self.list.win,
|
||||
preview = self.preview.win,
|
||||
preview = not preview_main and self.preview.win or nil,
|
||||
},
|
||||
hidden = { layout.preview == false and "preview" or nil },
|
||||
hidden = { preview_hidden and "preview" or nil },
|
||||
on_update = function()
|
||||
self:update_titles()
|
||||
end,
|
||||
layout = {
|
||||
backdrop = backdrop,
|
||||
},
|
||||
}))
|
||||
self.preview:update(preview_main and self.parent_win or nil)
|
||||
-- apply box highlight groups
|
||||
local boxwhl = Snacks.picker.highlight.winhl("SnacksPickerBox")
|
||||
for _, win in pairs(self.layout.box_wins) do
|
||||
|
@ -246,6 +257,9 @@ function M:show()
|
|||
end
|
||||
self.shown = true
|
||||
self.layout:show()
|
||||
if self.preview.main then
|
||||
self.preview.win:show()
|
||||
end
|
||||
self.input.win:focus()
|
||||
end
|
||||
|
||||
|
@ -290,6 +304,7 @@ function M:close()
|
|||
if (current == self.input.win.win or current == self.list.win.win) and vim.api.nvim_win_is_valid(self.parent_win) then
|
||||
vim.api.nvim_set_current_win(self.parent_win)
|
||||
end
|
||||
self.preview.win:close()
|
||||
self.layout:close()
|
||||
self.updater:stop()
|
||||
M._active[self] = nil
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
---@field win snacks.win
|
||||
---@field previewer snacks.picker.Previewer
|
||||
---@field state table<string, any>
|
||||
---@field main? number
|
||||
---@field win_opts {main: snacks.win.Config, layout: snacks.win.Config, win: snacks.win.Config}
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
|
@ -18,26 +20,45 @@ local ns = vim.api.nvim_create_namespace("snacks.picker.preview")
|
|||
local ns_loc = vim.api.nvim_create_namespace("snacks.picker.preview.loc")
|
||||
|
||||
---@param opts snacks.picker.Config
|
||||
function M.new(opts)
|
||||
---@param main? number
|
||||
function M.new(opts, main)
|
||||
local self = setmetatable({}, M)
|
||||
self.win = Snacks.win(Snacks.win.resolve(
|
||||
local win_opts = Snacks.win.resolve(
|
||||
{
|
||||
title_pos = "center",
|
||||
},
|
||||
opts.win.preview,
|
||||
{
|
||||
show = false,
|
||||
enter = false,
|
||||
width = 0,
|
||||
height = 0,
|
||||
fixbuf = false,
|
||||
wo = {
|
||||
winhighlight = Snacks.picker.highlight.winhl("SnacksPickerPreview"),
|
||||
},
|
||||
bo = { filetype = "snacks_picker_preview" },
|
||||
on_win = function()
|
||||
self.item = nil
|
||||
self:reset()
|
||||
end,
|
||||
}
|
||||
))
|
||||
)
|
||||
self.win_opts = {
|
||||
main = {
|
||||
relative = "win",
|
||||
backdrop = false,
|
||||
wo = {
|
||||
winhighlight = "NormalFloat:Normal",
|
||||
},
|
||||
},
|
||||
layout = {
|
||||
backdrop = win_opts.backdrop == true,
|
||||
relative = "win",
|
||||
wo = {
|
||||
winhighlight = Snacks.picker.highlight.winhl("SnacksPickerPreview"),
|
||||
},
|
||||
},
|
||||
}
|
||||
self.win = Snacks.win(win_opts)
|
||||
self:update(main)
|
||||
self.state = {}
|
||||
|
||||
self.win:on("WinClosed", function()
|
||||
|
@ -51,6 +72,16 @@ function M.new(opts)
|
|||
return self
|
||||
end
|
||||
|
||||
---@param main? number
|
||||
function M:update(main)
|
||||
self.main = main
|
||||
self.win_opts.main.win = main
|
||||
self.win.opts = vim.tbl_deep_extend("force", self.win.opts, main and self.win_opts.main or self.win_opts.layout)
|
||||
if self.win:valid() then
|
||||
self.win:update()
|
||||
end
|
||||
end
|
||||
|
||||
---@param picker snacks.Picker
|
||||
function M:preview(picker)
|
||||
local item = picker:current()
|
||||
|
|
|
@ -522,6 +522,9 @@ end
|
|||
---@param title string
|
||||
---@param pos? "center"|"left"|"right"
|
||||
function M:set_title(title, pos)
|
||||
if not self:has_border() then
|
||||
return
|
||||
end
|
||||
title = vim.trim(title)
|
||||
if title ~= "" then
|
||||
-- HACK: add extra space when last char is non word
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue