From 5c16ea9f555126a63c675c2ef8b8f4c444a728f9 Mon Sep 17 00:00:00 2001 From: bee4come Date: Fri, 30 Jan 2026 08:40:24 +0000 Subject: [PATCH] fix(tui): add eslint-disable for intentional control character regex The regex is intentionally matching ANSI escape sequences which contain control characters. Added disable comment and fixed formatting. --- src/tui/components/searchable-select-list.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tui/components/searchable-select-list.ts b/src/tui/components/searchable-select-list.ts index e722e1cc2..68265525e 100644 --- a/src/tui/components/searchable-select-list.ts +++ b/src/tui/components/searchable-select-list.ts @@ -143,11 +143,12 @@ export class SearchableSelectList implements Component { for (const token of uniqueTokens) { // CRITICAL FIX: Skip ANSI escape sequences to avoid breaking color codes // Split text into ANSI and visible parts, only highlight visible parts + // eslint-disable-next-line no-control-regex -- intentional: matching ANSI escape sequences const ansiRegex = /\x1b\[[0-9;]*m/g; const parts: Array<{ text: string; isAnsi: boolean }> = []; let lastIndex = 0; let match: RegExpExecArray | null; - + while ((match = ansiRegex.exec(text)) !== null) { if (match.index > lastIndex) { parts.push({ text: text.slice(lastIndex, match.index), isAnsi: false }); @@ -158,7 +159,7 @@ export class SearchableSelectList implements Component { if (lastIndex < text.length) { parts.push({ text: text.slice(lastIndex), isAnsi: false }); } - + // Only highlight in non-ANSI parts const regex = this.getCachedRegex(token); result = parts @@ -168,7 +169,7 @@ export class SearchableSelectList implements Component { return part.text.replace(regex, (m) => this.theme.matchHighlight(m)); }) .join(""); - + // Update text for next token iteration text = result; } @@ -233,7 +234,7 @@ export class SearchableSelectList implements Component { private ensureLineWidth(text: string, width: number): string { // Use pi-tui's visibleWidth for accurate measurement const currentWidth = visibleWidth(text); - + if (currentWidth <= width) { return text; } @@ -273,9 +274,7 @@ export class SearchableSelectList implements Component { const truncatedDesc = truncateToWidth(item.description, remainingWidth, ""); // Highlight first, then apply theme - avoids breaking ANSI codes const highlightedDesc = this.highlightMatch(truncatedDesc, query); - const descText = isSelected - ? highlightedDesc - : this.theme.description(highlightedDesc); + const descText = isSelected ? highlightedDesc : this.theme.description(highlightedDesc); const line = `${prefix}${valueText}${spacing}${descText}`; const rendered = isSelected ? this.theme.selectedText(line) : line; return this.ensureLineWidth(rendered, width);