mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 14:01:06 +00:00
Fix viewport width issues in thinking selector and text rendering
Thinking selector fix: - Replace hardcoded 50-character borders with DynamicBorder component that adjusts to viewport width - Prevents crash when terminal is resized narrow Text/Markdown rendering fixes: - Fix Markdown wrapSingleLine to check if adding next character would exceed width BEFORE adding it (was checking AFTER, causing lines to be 1 character too long) - Add word truncation in Text component for words longer than contentWidth (prevents long unbreakable words from exceeding width) These fixes prevent "Rendered line exceeds terminal width" errors.
This commit is contained in:
parent
a3b3849188
commit
02a21dd936
3 changed files with 37 additions and 11 deletions
|
|
@ -1,7 +1,16 @@
|
|||
import type { ThinkingLevel } from "@mariozechner/pi-agent";
|
||||
import { Container, type SelectItem, SelectList, Text } from "@mariozechner/pi-tui";
|
||||
import { type Component, Container, type SelectItem, SelectList } from "@mariozechner/pi-tui";
|
||||
import chalk from "chalk";
|
||||
|
||||
/**
|
||||
* Dynamic border component that adjusts to viewport width
|
||||
*/
|
||||
class DynamicBorder implements Component {
|
||||
render(width: number): string[] {
|
||||
return [chalk.blue("─".repeat(Math.max(1, width)))];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component that renders a thinking level selector with borders
|
||||
*/
|
||||
|
|
@ -20,7 +29,7 @@ export class ThinkingSelectorComponent extends Container {
|
|||
];
|
||||
|
||||
// Add top border
|
||||
this.addChild(new Text(chalk.blue("─".repeat(50)), 0, 0));
|
||||
this.addChild(new DynamicBorder());
|
||||
|
||||
// Create selector
|
||||
this.selectList = new SelectList(thinkingLevels, 5);
|
||||
|
|
@ -42,7 +51,7 @@ export class ThinkingSelectorComponent extends Container {
|
|||
this.addChild(this.selectList);
|
||||
|
||||
// Add bottom border
|
||||
this.addChild(new Text(chalk.blue("─".repeat(50)), 0, 0));
|
||||
this.addChild(new DynamicBorder());
|
||||
}
|
||||
|
||||
getSelectList(): SelectList {
|
||||
|
|
|
|||
|
|
@ -404,7 +404,11 @@ export class Markdown implements Component {
|
|||
}
|
||||
} else {
|
||||
// Regular character
|
||||
if (currentLength >= width) {
|
||||
const char = line[i];
|
||||
const charWidth = visibleWidth(char);
|
||||
|
||||
// Check if adding this character would exceed width
|
||||
if (currentLength + charWidth > width) {
|
||||
// Need to wrap - close current line with reset if needed
|
||||
if (activeAnsiCodes.length > 0) {
|
||||
wrapped.push(currentLine + "\x1b[0m");
|
||||
|
|
@ -416,10 +420,9 @@ export class Markdown implements Component {
|
|||
}
|
||||
currentLength = 0;
|
||||
}
|
||||
const char = line[i];
|
||||
|
||||
currentLine += char;
|
||||
// Count actual terminal column width, not string length
|
||||
currentLength += visibleWidth(char);
|
||||
currentLength += charWidth;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,13 +84,27 @@ export class Text implements Component {
|
|||
const currentVisible = visibleWidth(currentLine);
|
||||
const wordVisible = visibleWidth(word);
|
||||
|
||||
// If word is too long, truncate it
|
||||
let finalWord = word;
|
||||
if (wordVisible > contentWidth) {
|
||||
// Truncate word to fit
|
||||
let truncated = "";
|
||||
for (const char of word) {
|
||||
if (visibleWidth(truncated + char) > contentWidth) {
|
||||
break;
|
||||
}
|
||||
truncated += char;
|
||||
}
|
||||
finalWord = truncated;
|
||||
}
|
||||
|
||||
if (currentVisible === 0) {
|
||||
currentLine = word;
|
||||
} else if (currentVisible + 1 + wordVisible <= contentWidth) {
|
||||
currentLine += " " + word;
|
||||
currentLine = finalWord;
|
||||
} else if (currentVisible + 1 + visibleWidth(finalWord) <= contentWidth) {
|
||||
currentLine += " " + finalWord;
|
||||
} else {
|
||||
lines.push(currentLine);
|
||||
currentLine = word;
|
||||
currentLine = finalWord;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue