local M = {} local Key = require('spacevim.api').import('vim.keys') M.__vim = require('spacevim.api').import('vim') local function echo(str) vim.api.nvim_echo({{str, 'Normal'}}, false, {}) end local function next_item(list, item) local id = vim.fn.index(list, item) if id == #list - 1 then return list[1] else return list[id + 2] end end local function previous_item(list, item) local id = vim.fn.index(list, item) if id == 0 then return list[#list] else return list[id] end end local function parse_items(items) local is = {} local id = 1 for _, item in ipairs(items) do is[id] = item is[id][1] = '(' .. id .. ')' .. item[1] id = id + 1 end return is end local function list_keys(l) if #l == 0 then return {} end return vim.fn.range(1, #l) end function M.menu(items) local cancelled = false local saved_more = vim.o.more local saved_cmdheight = vim.o.cmdheight vim.o.more = false items = parse_items(items) vim.o.cmdheight = #items + 1 vim.cmd('redrawstatus!') local selected = 1 local exit = false local indent = string.rep(' ', 7, '') while not exit do local menu = 'Cmdline menu: Use j/k/enter and the shortcuts indicated\n' local id = 1 for _, _ in pairs(items) do if id == selected then menu = menu .. indent .. '>' .. items[id][1] .. '\n' else menu = menu .. indent .. ' ' .. items[id][1] .. '\n' end id = id + 1 end vim.cmd('redraw!') echo(string.sub(menu, 1, #menu - 1)) local char = M.__vim.getchar() if char == Key.t('') or char == Key.t('') then exit = true cancelled = true vim.cmd('normal! :') elseif vim.fn.index(list_keys(items), tonumber(char)) ~= -1 or char == Key.t('') then if char ~= Key.t('') then selected = tonumber(char, 10) end local value = items[selected][2] vim.cmd('normal! :') if type(value) == "function" then local args = items[selected][3] or {} local ok, err = pcall(value, unpack(args)) if not ok then print(err) end elseif type(value) == 'string' then vim.cmd(value) end exit = true elseif char == 'j' or char == Key.t('') then selected = next_item(list_keys(items), selected) vim.cmd('normal! :') elseif char == 'k' or char == Key.t('') then selected = previous_item(list_keys(items), selected) vim.cmd('normal! :') else vim.cmd('normal! :') end end vim.o.more = saved_more vim.o.cmdheight = saved_cmdheight vim.cmd('redraw!') if cancelled then echo('cancelled!') end end return M