|
| 1 | +local config = require('opencode.config') |
| 2 | +local util = require('opencode.util') |
| 3 | +local M = {} |
| 4 | + |
| 5 | +---@class PickerItem |
| 6 | +---@field content string Main content text |
| 7 | +---@field time_text? string Optional time text |
| 8 | +---@field debug_text? string Optional debug text |
| 9 | +---@field to_string fun(self: PickerItem): string |
| 10 | +---@field to_formatted_text fun(self: PickerItem): string, table |
| 11 | + |
| 12 | +---@param text? string |
| 13 | +---@param width integer |
| 14 | +---@param opts? {align?: "left" | "right" | "center", truncate?: boolean} |
| 15 | +function M.align(text, width, opts) |
| 16 | + text = text or '' |
| 17 | + opts = opts or {} |
| 18 | + opts.align = opts.align or 'left' |
| 19 | + local tw = vim.api.nvim_strwidth(text) |
| 20 | + if tw > width then |
| 21 | + return opts.truncate and (vim.fn.strcharpart(text, 0, width - 1) .. '…') or text |
| 22 | + end |
| 23 | + local left = math.floor((width - tw) / 2) |
| 24 | + local right = width - tw - left |
| 25 | + if opts.align == 'left' then |
| 26 | + left, right = 0, width - tw |
| 27 | + elseif opts.align == 'right' then |
| 28 | + left, right = width - tw, 0 |
| 29 | + end |
| 30 | + return (' '):rep(left) .. text .. (' '):rep(right) |
| 31 | +end |
| 32 | + |
| 33 | +---Creates a generic picker item that can format itself for different pickers |
| 34 | +---@param text string Array of text parts to join |
| 35 | +---@param time? number Optional time text to highlight |
| 36 | +---@param debug_text? string Optional debug text to append |
| 37 | +---@return PickerItem |
| 38 | +function M.create_picker_item(text, time, debug_text) |
| 39 | + local debug_offset = config.debug.show_ids and #debug_text or 0 |
| 40 | + local item = { |
| 41 | + content = M.align(text, 70 - debug_offset + 1, { truncate = true }), |
| 42 | + time_text = time and M.align(util.format_time(time), 20, { align = 'right' }), |
| 43 | + debug_text = config.debug.show_ids and debug_text or nil, |
| 44 | + } |
| 45 | + |
| 46 | + function item:to_string() |
| 47 | + local segments = { self.content } |
| 48 | + |
| 49 | + if self.time_text then |
| 50 | + table.insert(segments, self.time_text) |
| 51 | + end |
| 52 | + |
| 53 | + if self.debug_text then |
| 54 | + table.insert(segments, self.debug_text) |
| 55 | + end |
| 56 | + |
| 57 | + return table.concat(segments, ' ') |
| 58 | + end |
| 59 | + |
| 60 | + function item:to_formatted_text() |
| 61 | + local segments = { { self.content } } |
| 62 | + |
| 63 | + if self.time_text then |
| 64 | + table.insert(segments, { ' ' .. self.time_text, 'OpencodePickerTime' }) |
| 65 | + end |
| 66 | + |
| 67 | + if self.debug_text then |
| 68 | + table.insert(segments, { ' ' .. self.debug_text, 'OpencodeDebugText' }) |
| 69 | + end |
| 70 | + |
| 71 | + return segments |
| 72 | + end |
| 73 | + |
| 74 | + return item |
| 75 | +end |
| 76 | + |
| 77 | +return M |
0 commit comments