dressing.nvim/lua/dressing/select/nui.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