local icon = require 'std.icon' local HELP_PATTERNS = { '^h$', '^he$', '^hel$', '^help$', '^h%s', '^help%s' } local BORDER_HIGHLIGHT_MAP = { search_down = { border = 'CmdlineBorderSearch', corner = 'CmdlineBorderCornerSearch' }, search_up = { border = 'CmdlineBorderSearch', corner = 'CmdlineBorderCornerSearch' }, shell = { border = 'CmdlineBorderShell', corner = 'CmdlineBorderCornerShell' }, help = { border = 'CmdlineBorderHelp', corner = 'CmdlineBorderCornerHelp' }, lua = { border = 'CmdlineBorderLua', corner = 'CmdlineBorderCornerLua' }, input = { border = 'CmdlineBorderInput', corner = 'CmdlineBorderCornerInput' }, cmdline = { border = 'CmdlineBorderCmdline', corner = 'CmdlineBorderCornerCmdline' }, } local ICON_HIGHLIGHT_MAP = { search_down = 'CmdlineIconSearch', search_up = 'CmdlineIconSearch', shell = 'CmdlineIconShell', help = 'CmdlineIconHelp', lua = 'CmdlineIconLua', input = 'CmdlineIconInput', cmdline = 'CmdlineIconCmdline', } return { detect = function(firstc, content, prompt) if prompt and prompt ~= '' then return { type = 'input', icon = icon.prompt_prefix, lang = nil } end if prompt == '' and firstc == '' then return { type = 'input', icon = icon.prompt_prefix, lang = nil } end if firstc == '/' then return { type = 'search_down', icon = icon.search, lang = 'regex' } end if firstc == '?' then return { type = 'search_up', icon = icon.search_up, lang = 'regex' } end if firstc == '!' or (firstc == ':' and content and content:match '^!') then return { type = 'shell', icon = icon.shell, lang = 'bash' } end if firstc == ':' and content then for _, pat in ipairs(HELP_PATTERNS) do if content:match(pat) then return { type = 'help', icon = icon.help, lang = nil } end end if content:match '^lua%s' or content:match '^lua$' or content:match '^=' then return { type = 'lua', icon = icon.vim, lang = 'lua' } end return { type = 'cmdline', icon = icon.command, lang = 'vim' } end return { type = 'cmdline', icon = icon.command, lang = 'vim' } end, border_highlight_map = BORDER_HIGHLIGHT_MAP, icon_highlight = function(type) return ICON_HIGHLIGHT_MAP[type] or 'CmdlineIconCmdline' end, winhighlight = function(type, base) local hl = BORDER_HIGHLIGHT_MAP[type] or BORDER_HIGHLIGHT_MAP.cmdline return string.format('Normal:%s,FloatBorder:%s,FloatBorderCorner:%s', base, hl.border, hl.corner) end, prompt_lines = function(prompt, max_width) if not prompt or prompt == '' then return {} end vim.validate('prompt', prompt, 'string') vim.validate('max_width', max_width, 'number') local lines = {} for line in (prompt .. '\n'):gmatch('([^\n]*)\n') do table.insert(lines, line) end if #lines > 0 and lines[#lines] == '' then table.remove(lines) end local result = {} for _, line in ipairs(lines) do if vim.fn.strdisplaywidth(line) <= max_width then table.insert(result, line) else local remaining = line while remaining ~= '' and vim.fn.strdisplaywidth(remaining) > max_width do local cutoff = 0 for i = 1, #remaining do if vim.fn.strdisplaywidth(remaining:sub(1, i)) > max_width then cutoff = i - 1 break end end if cutoff == 0 then cutoff = math.min(max_width, #remaining) end local chunk = remaining:sub(1, cutoff) local last_space = chunk:match '()%s[^%s]*$' if last_space and last_space > 1 then local ws = chunk:match '%s+[^%s]*$' cutoff = #chunk - #ws chunk = chunk:sub(1, cutoff):gsub('%s+$', '') end table.insert(result, chunk) remaining = remaining:sub(cutoff + 1):gsub('^%s+', '') end if remaining ~= '' then table.insert(result, remaining) end end end return result end, PROMPT_MAX_RATIO = 0.85, }