mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-22 07:38:12 +00:00
perf(terminal): reuse ANSI truncation scanner
Reuse one module-level ANSI/OSC scanner during visible-width truncation and reset scanner state between calls. Keeps styled, plain, and OSC-8 truncation behavior covered by regression tests.
This commit is contained in:
@@ -60,4 +60,13 @@ describe("terminal ansi helpers", () => {
|
||||
expect(truncateToVisibleWidth("[31m表文[0m", 1)).toBe("[31m[0m");
|
||||
expect(visibleWidth(truncateToVisibleWidth("[31m表文[0m", 1))).toBe(0);
|
||||
});
|
||||
|
||||
it("reuses the ANSI scanner across truncation calls", () => {
|
||||
expect(truncateToVisibleWidth("\u001B[31mabc\u001B[0m", 2)).toBe("\u001B[31mab\u001B[0m");
|
||||
expect(truncateToVisibleWidth("plain", 3)).toBe("pla");
|
||||
expect(
|
||||
truncateToVisibleWidth("\u001B]8;;https://openclaw.ai\u001B\\link\u001B]8;;\u001B\\", 2),
|
||||
).toBe("\u001B]8;;https://openclaw.ai\u001B\\li\u001B]8;;\u001B\\");
|
||||
expect(truncateToVisibleWidth("\u001B[32mxy\u001B[0m", 1)).toBe("\u001B[32mx\u001B[0m");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ const ANSI_OSC_PATTERN = "\\x1b\\][^\\x07\\x1b]*(?:\\x1b\\\\|\\x07)";
|
||||
|
||||
const ANSI_CSI_REGEX = new RegExp(ANSI_CSI_PATTERN, "g");
|
||||
const ANSI_OSC_REGEX = new RegExp(ANSI_OSC_PATTERN, "g");
|
||||
const ANSI_SEQUENCE_REGEX = new RegExp(`${ANSI_OSC_PATTERN}|${ANSI_CSI_PATTERN}`, "g");
|
||||
const graphemeSegmenter =
|
||||
typeof Intl !== "undefined" && "Segmenter" in Intl
|
||||
? new Intl.Segmenter(undefined, { granularity: "grapheme" })
|
||||
@@ -134,7 +135,7 @@ export function truncateToVisibleWidth(input: string, maxWidth: number): string
|
||||
if (visibleWidth(input) <= maxWidth) {
|
||||
return input;
|
||||
}
|
||||
const ansi = new RegExp(`${ANSI_OSC_PATTERN}|${ANSI_CSI_PATTERN}`, "g");
|
||||
ANSI_SEQUENCE_REGEX.lastIndex = 0;
|
||||
let out = "";
|
||||
let used = 0;
|
||||
let pos = 0;
|
||||
@@ -157,7 +158,7 @@ export function truncateToVisibleWidth(input: string, maxWidth: number): string
|
||||
}
|
||||
};
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = ansi.exec(input)) !== null) {
|
||||
while ((match = ANSI_SEQUENCE_REGEX.exec(input)) !== null) {
|
||||
appendVisible(input.slice(pos, match.index));
|
||||
out += match[0];
|
||||
pos = match.index + match[0].length;
|
||||
|
||||
Reference in New Issue
Block a user