improve(terminal): speed up fitting table rendering (#127221)

* test(terminal): cover fitting table cell rendering

Amp-Thread-ID: https://ampcode.com/threads/T-01a0242a-0302-708f-a777-ec7c0a5c9c60

* perf(terminal): skip wrapping work for fitting ASCII cells

Amp-Thread-ID: https://ampcode.com/threads/T-01a021f5-984a-7628-a30c-491c166ff247

---------

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-21 07:37:16 -07:00
committed by GitHub
parent 2cbfade48b
commit 7d83ff7c8f
2 changed files with 23 additions and 2 deletions
+15
View File
@@ -70,6 +70,21 @@ describe("renderTable", () => {
vi.restoreAllMocks();
});
it("renders fitting ASCII cells without grapheme segmentation", () => {
const segment = vi.spyOn(Intl.Segmenter.prototype, "segment");
const out = renderTable({
border: "ascii",
columns: [{ key: "Name", header: "Name" }],
rows: [{ Name: "alpha" }, { Name: "beta" }],
});
expect(out).toBe(
["+-------+", "| Name |", "+-------+", "| alpha |", "| beta |", "+-------+", ""].join("\n"),
);
expect(segment).not.toHaveBeenCalled();
});
it.each(["$&", "$`", "$'", "$$"])(
"displays a literal %s home path in terminal tables",
(pattern) => {
+8 -2
View File
@@ -55,8 +55,9 @@ function padCell(text: string, width: number, align: Align): string {
// A single grapheme wider than the cell (e.g. a width-2 CJK/emoji glyph in a
// width-1 column) survives wrapLine intact, so clamp here to keep every cell
// exactly `width` columns and preserve the border-alignment invariant.
const content = visibleWidth(text) > width ? truncateToVisibleWidth(text, width) : text;
const w = visibleWidth(content);
const textWidth = visibleWidth(text);
const content = textWidth > width ? truncateToVisibleWidth(text, width) : text;
const w = content === text ? textWidth : visibleWidth(content);
if (w >= width) {
return content;
}
@@ -366,6 +367,11 @@ function wrapLine(text: string, width: number): string[] {
if (width <= 0) {
return [text];
}
// Fitting edge-trimmed ASCII is one column per code unit and needs no ANSI/grapheme scan.
// Keep edge whitespace on the full path, where wrapping preserves its trimming semantics.
if (text.length <= width && /^[!-~](?:[ -~]*[!-~])?$/u.test(text)) {
return [text];
}
// ANSI-aware wrapping: never split inside ANSI SGR/OSC-8 sequences.
// Table cells are padded and bordered per physical line, so wrapped lines