import type { Theme } from "@earendil-works/pi-coding-agent"; import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui"; /** pi-core keybinding-hint convention: dim key + muted description. */ export function hintLine(th: Theme, pairs: Array<[string, string]>): string { return " " + pairs.map(([k, d]) => th.fg("dim", k) + th.fg("muted", ` ${d}`)).join(" "); } /** * Render highest-priority hints that fit, without letting navigation displace * the primary action or cancel. pi-tui measures display cells after stripping * ANSI sequences, so CJK and themed hints remain width-safe. */ export function prioritizedHintLine(th: Theme, pairs: Array<[string, string]>, width: number, ellipsis: string): string { const full = hintLine(th, pairs); if (visibleWidth(full) <= width) return full; let prefix = ""; for (const pair of pairs) { const hint = hintLine(th, [pair]); const candidate = prefix ? `${prefix} ${hint.trimStart()}` : hint; // Reserve the truncation marker before accepting each complete hint. Once // a higher-priority hint cannot fit, no lower-priority hint may replace it. if (visibleWidth(`${candidate} ${ellipsis}`) > width) break; prefix = candidate; } return prefix ? `${prefix} ${ellipsis}` : truncateToWidth(ellipsis, width, ""); }