73 lines
1.7 KiB
Lua
73 lines
1.7 KiB
Lua
local M = {}
|
|
|
|
M.is_supported = function()
|
|
return pcall(require, "nui.menu")
|
|
end
|
|
|
|
M.select = function(config, items, opts, on_choice)
|
|
local Menu = require("nui.menu")
|
|
local event = require("nui.utils.autocmd").event
|
|
local lines = {}
|
|
local line_width = opts.prompt and vim.api.nvim_strwidth(opts.prompt) or 1
|
|
for i, item in ipairs(items) do
|
|
local line = opts.format_item(item)
|
|
line_width = math.max(line_width, vim.api.nvim_strwidth(line))
|
|
table.insert(lines, Menu.item(line, { value = item, idx = i }))
|
|
end
|
|
|
|
if not config.size then
|
|
line_width = math.max(line_width, config.min_width)
|
|
local height = math.max(#lines, config.min_height)
|
|
config.size = {
|
|
width = line_width,
|
|
height = height,
|
|
}
|
|
end
|
|
|
|
local callback
|
|
callback = function(...)
|
|
on_choice(...)
|
|
-- Prevent double-calls
|
|
callback = function() end
|
|
end
|
|
|
|
local border = vim.deepcopy(config.border)
|
|
border.text = {
|
|
top = opts.prompt,
|
|
top_align = "center",
|
|
}
|
|
local menu = Menu({
|
|
position = config.position,
|
|
size = config.size,
|
|
relative = config.relative,
|
|
border = border,
|
|
buf_options = config.buf_options,
|
|
win_options = config.win_options,
|
|
enter = true,
|
|
}, {
|
|
lines = lines,
|
|
max_width = config.max_width,
|
|
max_height = config.max_height,
|
|
keymap = {
|
|
focus_next = { "j", "<Down>", "<Tab>" },
|
|
focus_prev = { "k", "<Up>", "<S-Tab>" },
|
|
close = { "<Esc>", "<C-c>" },
|
|
submit = { "<CR>" },
|
|
},
|
|
on_close = function()
|
|
vim.schedule(function()
|
|
callback(nil, nil)
|
|
end)
|
|
end,
|
|
on_submit = function(item)
|
|
callback(item.value, item.idx)
|
|
end,
|
|
})
|
|
|
|
menu:mount()
|
|
|
|
menu:on(event.BufLeave, menu.menu_props.on_close, { once = true })
|
|
end
|
|
|
|
return M
|