local wait = require('async.waits.wait') local List = require('java-core.utils.list') local M = {} ---Async vim.ui.select function ---@generic T ---@param prompt string ---@param values T[] ---@param format_item? fun(item: T): string ---@param opts? { return_one: boolean } ---@return T | nil function M.select(prompt, values, format_item, opts) opts = opts or { prompt_single = false } return wait(function(callback) if not opts.prompt_single and #values == 1 then callback(values[1]) return end vim.ui.select(values, { prompt = prompt, format_item = format_item, }, callback) end) end --Sync vim.ui.select function ---@generic T ---@param prompt string ---@param values T[] ---@param format_item? fun(item: T, index: number): string ---@param opts? { return_one: boolean } ---@return T | nil function M.select_sync(prompt, values, format_item, opts) opts = opts or { prompt_single = false } if not opts.prompt_single and #values == 1 then return values[1] end local labels = { prompt } for index, value in ipairs(values) do table.insert(labels, format_item and format_item(value, index) or value) end local selected_index = vim.fn.inputlist(labels) return values[selected_index] end ---Async vim.ui.select function ---@generic T ---@param prompt string ---@param values T[] ---@param format_item? fun(item: T): string ---@return T[] | nil function M.multi_select(prompt, values, format_item) return wait(function(callback) local wrapped_items = List:new(values):map(function(item, index) return { index = index, is_selected = false, value = item, } end) local open_select open_select = function() vim.ui.select(wrapped_items, { prompt = prompt, format_item = function(item) local prefix = item.is_selected and '* ' or '' return prefix .. (format_item and format_item(item.value) or item.value) end, }, function(selected) if not selected then local selected_items = wrapped_items :filter(function(item) return item.is_selected end) :map(function(item) return item.value end) callback(#selected_items > 0 and selected_items or nil) return end wrapped_items[selected.index].is_selected = not wrapped_items[selected.index].is_selected open_select() end) end open_select() end) end function M.input(prompt) return wait(function(callback) vim.ui.input({ prompt = prompt, }, callback) end) end return M