render.ts
1366 bytes
1import type { Theme } from "@earendil-works/pi-coding-agent";
2import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
4export function fit(text: string, width: number): string {
5 const truncated = truncateToWidth(text, Math.max(0, width));
6 const padding = Math.max(0, width - visibleWidth(truncated));
7 return `${truncated}${" ".repeat(padding)}`;
8}
9
10export function frameLine(theme: Theme, content: string, innerWidth: number): string {
11 return `${theme.fg("borderAccent", "│")}${fit(content, innerWidth)}${theme.fg("borderAccent", "│")}`;
12}
13
14export function divider(theme: Theme, innerWidth: number): string {
15 return theme.fg("borderMuted", `├${"─".repeat(innerWidth)}┤`);
16}
17
18export function topBorder(theme: Theme, innerWidth: number): string {
19 return theme.fg("borderAccent", `┌${"─".repeat(innerWidth)}┐`);
20}
21
22export function bottomBorder(theme: Theme, innerWidth: number): string {
23 return theme.fg("borderAccent", `└${"─".repeat(innerWidth)}┘`);
24}
25
26export function combineColumns(left: string[], right: string[], leftWidth: number, rightWidth: number, sep: string): string[] {
27 const rows = Math.max(left.length, right.length);
28 const lines: string[] = [];
29 for (let i = 0; i < rows; i += 1) {
30 lines.push(`${fit(left[i] ?? "", leftWidth)}${sep}${fit(right[i] ?? "", rightWidth)}`);
31 }
32 return lines;
33}