UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

55 lines (54 loc) • 2.3 kB
/** * Width-safe line fitting for TUI rendering (shared by the footer widget and * the turn-summary message renderer). pi-tui's `TUI.doRender` HARD-CRASHES the * whole host on any rendered line wider than the terminal ("Rendered line N * exceeds terminal width") — every `Component.render(width)` line MUST be * truncated to the given width. Seen live 2026-07-11: an untruncated * turn-summary one-liner (133 cols vs 120) took down a pi session (#513). * * Two incompatible truncateToWidth signatures ship under the * "@earendil-works/pi-tui" specifier depending on which runtime resolves it: * - pure-JS pi-tui: (text, maxWidth, ellipsis: string, pad?) * - native @oh-my-pi >=16: (text, maxWidth, ellipsisKind: Ellipsis enum, pad, tabWidth: i32) * Passing a string to the native one throws "Failed to convert napi value into * enum `Ellipsis`". Probe the string API once; on napi failure, switch to the * native enum signature for good. Ellipsis enum: Unicode=0 ("…"), Ascii=1 * ("..."), Omit=2. */ import { truncateToWidth } from "./deps/pi-tui.js"; const ELLIPSIS_KIND = { "…": 0, "...": 1, "": 2 }; let truncateIsNative = null; /** Test-only: reset the signature probe between test cases. */ export function _resetTruncateProbeForTests() { truncateIsNative = null; } export function fitLine(s, maxWidth, ellipsis = "...") { const w = Math.max(0, maxWidth); const fn = truncateToWidth; if (truncateIsNative === true) { return fn(s, w, ELLIPSIS_KIND[ellipsis] ?? 1, false, 8); } if (truncateIsNative === false) { return fn(s, w, ellipsis); } // first call: try the legacy string API; native binding rejects the string arg. try { const out = fn(s, w, ellipsis); truncateIsNative = false; return out; } catch { truncateIsNative = true; return fn(s, w, ELLIPSIS_KIND[ellipsis] ?? 1, false, 8); } } /** * Fit every line of a `Component.render(width)` result. `width` can arrive as * 0/undefined in exotic hosts — treat non-positive as "don't truncate" rather * than emitting empty lines. */ export function fitLines(lines, width) { if (!Number.isFinite(width) || width <= 0) return lines; return lines.map((line) => fitLine(line, width)); }