Refactor trimLineEndPreserveAnsi to simpler regex approach
This commit is contained in:
parent
a90da23cbc
commit
0489864652
1 changed files with 6 additions and 29 deletions
35
src/ansi.ts
35
src/ansi.ts
|
|
@ -55,40 +55,17 @@ interface ExtendedColorResult {
|
||||||
|
|
||||||
// Trim trailing whitespace from each line to prevent background color bleeding.
|
// Trim trailing whitespace from each line to prevent background color bleeding.
|
||||||
// Terminal buffers often pad lines with spaces. Preserve trailing ANSI resets.
|
// Terminal buffers often pad lines with spaces. Preserve trailing ANSI resets.
|
||||||
// ESC character code
|
|
||||||
const ESC = "\x1b";
|
|
||||||
|
|
||||||
export function trimLineEndPreserveAnsi(line: string): string {
|
export function trimLineEndPreserveAnsi(line: string): string {
|
||||||
// Peel off any ANSI sequences at the end of the line
|
|
||||||
let end = line.length;
|
let end = line.length;
|
||||||
let ansiSuffix = "";
|
let ansiSuffix = "";
|
||||||
while (end > 0) {
|
while (end > 0) {
|
||||||
// Check for ANSI escape sequence at end: ESC [ params letter
|
// biome-ignore lint/suspicious/noControlCharactersInRegex: ESC character is intentional for ANSI sequences
|
||||||
const suffix = line.slice(0, end);
|
const match = line.slice(0, end).match(/\u001b\[[0-9;?]*[A-Za-z]$/);
|
||||||
if (!suffix.endsWith("]")) {
|
if (!match) break;
|
||||||
// Look for the closing letter (A-Z, a-z)
|
ansiSuffix = match[0] + ansiSuffix;
|
||||||
const lastChar = suffix[suffix.length - 1];
|
end -= match[0].length;
|
||||||
if (!lastChar || !/[A-Za-z]/.test(lastChar)) break;
|
|
||||||
|
|
||||||
// Walk back to find ESC [
|
|
||||||
let seqStart = suffix.length - 2;
|
|
||||||
while (seqStart >= 0 && /[0-9;?]/.test(suffix[seqStart] || "")) {
|
|
||||||
seqStart--;
|
|
||||||
}
|
|
||||||
if (seqStart < 0 || suffix[seqStart] !== "[") break;
|
|
||||||
seqStart--;
|
|
||||||
if (seqStart < 0 || suffix[seqStart] !== ESC) break;
|
|
||||||
|
|
||||||
// Found a valid ANSI sequence
|
|
||||||
const seq = suffix.slice(seqStart);
|
|
||||||
ansiSuffix = seq + ansiSuffix;
|
|
||||||
end = seqStart;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const trimmed = line.slice(0, end).trimEnd();
|
return line.slice(0, end).trimEnd() + ansiSuffix;
|
||||||
return trimmed + ansiSuffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse extended color: 38;2;R;G;B (24-bit) or 38;5;N (256-color)
|
// Parse extended color: 38;2;R;G;B (24-bit) or 38;5;N (256-color)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue