Download packages/pi-tui/src/components/text.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 3.36 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/pi-tui/src/components/text.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/pi-tui/src/components/text.ts
-
curl -L -o text.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/pi-tui/src/components/text.ts
3.36 kB
| import type { Component } from "../tui.ts"; | |
| import { applyBackgroundToLine, visibleWidth, wrapTextWithAnsi } from "../utils.ts"; | |
| /** | |
| * Text component - displays multi-line text with word wrapping | |
| */ | |
| export class Text implements Component { | |
| private text: string; | |
| private paddingX: number; // Left/right padding | |
| private paddingY: number; // Top/bottom padding | |
| private customBgFn?: (text: string) => string; | |
| // Cache for rendered output | |
| private cachedText?: string; | |
| private cachedWidth?: number; | |
| private cachedLines?: string[]; | |
| constructor(text: string = "", paddingX: number = 1, paddingY: number = 1, customBgFn?: (text: string) => string) { | |
| this.text = text; | |
| this.paddingX = paddingX; | |
| this.paddingY = paddingY; | |
| this.customBgFn = customBgFn; | |
| } | |
| setText(text: string): void { | |
| this.text = text; | |
| this.cachedText = undefined; | |
| this.cachedWidth = undefined; | |
| this.cachedLines = undefined; | |
| } | |
| setCustomBgFn(customBgFn?: (text: string) => string): void { | |
| this.customBgFn = customBgFn; | |
| this.cachedText = undefined; | |
| this.cachedWidth = undefined; | |
| this.cachedLines = undefined; | |
| } | |
| invalidate(): void { | |
| this.cachedText = undefined; | |
| this.cachedWidth = undefined; | |
| this.cachedLines = undefined; | |
| } | |
| render(width: number): string[] { | |
| // Check cache | |
| if (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) { | |
| return this.cachedLines; | |
| } | |
| // Don't render anything if there's no actual text | |
| if (!this.text || this.text.trim() === "") { | |
| const result: string[] = []; | |
| this.cachedText = this.text; | |
| this.cachedWidth = width; | |
| this.cachedLines = result; | |
| return result; | |
| } | |
| // Replace tabs with 3 spaces | |
| const normalizedText = this.text.replace(/\t/g, " "); | |
| // Reduce margins when necessary so content and padding fit within the available width. | |
| const paddingX = Math.min(this.paddingX, Math.max(0, Math.floor((width - 1) / 2))); | |
| const contentWidth = Math.max(1, width - paddingX * 2); | |
| // Wrap text (this preserves ANSI codes but does NOT pad) | |
| const wrappedLines = wrapTextWithAnsi(normalizedText, contentWidth); | |
| // Add margins and background to each line | |
| const leftMargin = " ".repeat(paddingX); | |
| const rightMargin = " ".repeat(paddingX); | |
| const contentLines: string[] = []; | |
| for (const line of wrappedLines) { | |
| // Add margins | |
| const lineWithMargins = leftMargin + line + rightMargin; | |
| // Apply background if specified (this also pads to full width) | |
| if (this.customBgFn) { | |
| contentLines.push(applyBackgroundToLine(lineWithMargins, width, this.customBgFn)); | |
| } else { | |
| // No background - just pad to width with spaces | |
| const visibleLen = visibleWidth(lineWithMargins); | |
| const paddingNeeded = Math.max(0, width - visibleLen); | |
| contentLines.push(lineWithMargins + " ".repeat(paddingNeeded)); | |
| } | |
| } | |
| // Add top/bottom padding (empty lines) | |
| const emptyLine = " ".repeat(Math.max(0, width)); | |
| const emptyLines: string[] = []; | |
| for (let i = 0; i < this.paddingY; i++) { | |
| const line = this.customBgFn ? applyBackgroundToLine(emptyLine, width, this.customBgFn) : emptyLine; | |
| emptyLines.push(line); | |
| } | |
| const result = [...emptyLines, ...contentLines, ...emptyLines]; | |
| // Update cache | |
| this.cachedText = this.text; | |
| this.cachedWidth = width; | |
| this.cachedLines = result; | |
| return result.length > 0 ? result : [""]; | |
| } | |
| } | |