Closed Ajaymamtora closed 1 month ago
Solved:
-- Update the hybrid layout code
function M.nui_hybrid_layout_fn(picker)
local Layout = require("nui.layout")
local Popup = require("nui.popup")
local telescope = require("telescope")
local TSLayout = require("telescope.pickers.layout")
local function make_popup(options)
local popup = Popup(options)
function popup.border:change_title(title)
popup.border.set_text(popup.border, "top", title)
end
return TSLayout.Window(popup)
end
local border = {
results = {
top_left = "┌",
top = "─",
top_right = "┬",
right = "│",
bottom_right = "",
bottom = "",
bottom_left = "",
left = "│",
},
results_patch = {
minimal = {
top_left = "┌",
top_right = "┐",
},
horizontal = {
top_left = "┌",
top_right = "┬",
},
vertical = {
top_left = "├",
top_right = "┤",
},
},
prompt = {
top_left = "├",
top = "─",
top_right = "┤",
right = "│",
bottom_right = "┘",
bottom = "─",
bottom_left = "└",
left = "│",
},
prompt_patch = {
minimal = {
bottom_right = "┘",
},
horizontal = {
bottom_right = "┴",
},
vertical = {
bottom_right = "┘",
},
},
preview = {
top_left = "┌",
top = "─",
top_right = "┐",
right = "│",
bottom_right = "┘",
bottom = "─",
bottom_left = "└",
left = "│",
},
preview_patch = {
minimal = {},
horizontal = {
bottom = "─",
bottom_left = "",
bottom_right = "┘",
left = "",
top_left = "",
},
vertical = {
bottom = "",
bottom_left = "",
bottom_right = "",
left = "│",
top_left = "┌",
},
},
}
local results = make_popup({
focusable = false,
border = {
style = border.results,
text = {
top = picker.results_title,
top_align = "center",
},
},
win_options = {
winhighlight = "Normal:Normal",
},
})
local prompt = make_popup({
enter = true,
border = {
style = border.prompt,
text = {
top = picker.prompt_title,
top_align = "center",
},
},
win_options = {
winhighlight = "Normal:Normal",
},
})
local preview = make_popup({
focusable = false,
border = {
style = border.preview,
text = {
top = picker.preview_title,
top_align = "center",
},
},
})
local box_by_kind = {
vertical = function()
if picker.previewer then
return Layout.Box({
Layout.Box(preview, { grow = 1 }),
Layout.Box(results, { grow = 1 }),
Layout.Box(prompt, { size = 3 }),
}, { dir = "col" })
else
return Layout.Box({
Layout.Box(results, { grow = 1 }),
Layout.Box(prompt, { size = 3 }),
}, { dir = "col" })
end
end,
horizontal = function()
if picker.previewer then
return Layout.Box({
Layout.Box({
Layout.Box(results, { grow = 1 }),
Layout.Box(prompt, { size = 3 }),
}, { dir = "col", size = "50%" }),
Layout.Box(preview, { size = "50%" }),
}, { dir = "row" })
else
return Layout.Box({
Layout.Box(results, { grow = 1 }),
Layout.Box(prompt, { size = 3 }),
}, { dir = "col" })
end
end,
minimal = Layout.Box({
Layout.Box(results, { grow = 1 }),
Layout.Box(prompt, { size = 3 }),
}, { dir = "col" }),
}
local function get_box()
local strategy = picker.layout_strategy
if strategy == "vertical" or strategy == "horizontal" then
return box_by_kind[strategy](), strategy
end
local height, width = vim.o.lines, vim.o.columns
local box_kind = "horizontal"
if width < 150 then
box_kind = "vertical"
if height < 40 then
box_kind = "minimal"
end
end
return (box_by_kind[box_kind] and box_by_kind[box_kind]()) or box_by_kind.minimal, box_kind
end
local function prepare_layout_parts(layout, box_type)
layout.results = results
results.border:set_style(border.results_patch[box_type])
layout.prompt = prompt
prompt.border:set_style(border.prompt_patch[box_type])
if box_type == "minimal" or not picker.previewer then
layout.preview = nil
else
layout.preview = preview
preview.border:set_style(border.preview_patch[box_type])
end
end
local function get_layout_size(box_kind)
return picker.layout_config[box_kind == "minimal" and "vertical" or box_kind].size
end
local box, box_kind = get_box()
local layout = Layout({
relative = "editor",
position = "50%",
size = get_layout_size(box_kind),
}, box)
layout.picker = picker
prepare_layout_parts(layout, box_kind)
local layout_update = layout.update
function layout:update()
local box, box_kind = get_box()
prepare_layout_parts(layout, box_kind)
layout_update(self, { size = get_layout_size(box_kind) }, box)
end
return TSLayout(layout)
end
...
-- call like this
M.small_pickers = {
"spell_suggest",
}
--- Calls a Telescope builtin picker with custom options for small pickers
---@param pickername string The name of the Telescope builtin picker
---@param opts table|nil Optional table of options to pass to the picker
function M.builtin(pickername, opts)
if not pickername then
return
end
local small_layout = {
layout_strategy = "vertical",
previewer = false,
layout_config = {
previewer = false,
vertical = {
previewer = false,
size = {
height = "40%",
width = "40%",
},
},
},
}
local builtin = require("telescope.builtin")[pickername]
if vim.tbl_contains(M.small_pickers, pickername) then
opts = vim.tbl_deep_extend("force", opts or {}, small_layout)
end
builtin(opts)
end
Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I use the nui hybrid layout from the recipe section and I use most pickers taking up most of the screen. I dont want certain pickers to do this however, for example if I trigger spell suggest I want it to open a smaller picker.
Describe the solution you'd like A clear and concise description of what you want to happen.
Allow for configuring specific sizes on open based on picker, e.g. when calling setup:
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
I can't figure out any alternatives. I tried checking the picker in create_layout but the only unique info I could find was the title of the picker which is a terrible way of doing it.
Additional context Add any other context or screenshots about the feature request here.
Can't see anything while trying to suggest a spelling:
But I do want a large picker when finding files for example: