local M = {} ---@class inbox.TextChunk ---@field [1] string text ---@field [2] string hl ---@param text string ---@param length nil|integer ---@return string function M.rpad(text, length) if not length then return text end if text:len() <= length then return text .. string.rep(" ", length - text:len()) else return string.sub(text, 1, length - 3) .. "..." end end ---@param cols (string | inbox.TextChunk)[] ---@param col_widths integer[] ---@return string ---@return any[][] List of highlights {group, col_start, col_end} function M.render_row(cols, col_widths) local pieces = {} local highlights = {} local col = 0 for i, chunk in ipairs(cols) do local text, hl if type(chunk) == "table" then text, hl = unpack(chunk) --[[@as string]] else text = chunk --[[@as string]] end text = M.rpad(text, col_widths[i]) table.insert(pieces, text) local col_end = col + text:len() + 1 if hl then table.insert(highlights, { hl, col, col_end }) end col = col_end end return table.concat(pieces, " "), highlights end ---@param rows (string | inbox.TextChunk)[][] ---@param col_widths integer[] ---@return string[] ---@return any[][] List of highlights {group, lnum, col_start, col_end} function M.render_table(rows, col_widths) local lines = {} local highlights = {} for lnum, cols in ipairs(rows) do local line, line_hls = M.render_row(cols, col_widths) table.insert(lines, line) for _, hl in pairs(line_hls) do local group, col_start, col_end = unpack(hl) table.insert(highlights, { group, lnum, col_start, col_end }) end end return lines, highlights end ---@param winid integer ---@param cols (string | inbox.TextChunk)[] ---@param col_widths integer[] function M.render_winbar(winid, cols, col_widths) local winbar = M.render_row(cols, col_widths) local offset = vim.fn.getwininfo(winid)[1].textoff + 1 vim.api.nvim_set_option_value("winbar", string.rep(" ", offset) .. winbar, { scope = "local", win = winid }) end return M