From 55867ffd7bbf1157487aa7e62250a0a13670ab80 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Fri, 10 Jul 2026 08:07:07 +0800 Subject: [PATCH] Fix fish prompt OSC highlighting (#998) --- src/ui/lib/terminal-syntax-highlighter.test.ts | 10 ++++++++++ src/ui/lib/terminal-syntax-highlighter.ts | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/ui/lib/terminal-syntax-highlighter.test.ts b/src/ui/lib/terminal-syntax-highlighter.test.ts index fc2b55f8..3e57b491 100644 --- a/src/ui/lib/terminal-syntax-highlighter.test.ts +++ b/src/ui/lib/terminal-syntax-highlighter.test.ts @@ -76,6 +76,16 @@ describe("highlightTerminalOutput", () => { expect(highlightTerminalOutput(chunk)).toBe(chunk); }); + it("skips OSC current-directory sequences used by fish prompts", () => { + const chunk = `${ESC}]7;file://server/home/user/docker/sonarr\x07user@server ~/docker/sonarr> `; + expect(highlightTerminalOutput(chunk)).toBe(chunk); + }); + + it("skips OSC title sequences", () => { + const chunk = `${ESC}]0;user@server:/var/log\x07ERROR after title`; + expect(highlightTerminalOutput(chunk)).toBe(chunk); + }); + it("highlights text that already has ANSI codes", () => { let heavy = ""; for (let i = 0; i < 12; i++) heavy += `${ESC}[32mgreen${ESC}[0m `; diff --git a/src/ui/lib/terminal-syntax-highlighter.ts b/src/ui/lib/terminal-syntax-highlighter.ts index aaba3615..7e6489d7 100644 --- a/src/ui/lib/terminal-syntax-highlighter.ts +++ b/src/ui/lib/terminal-syntax-highlighter.ts @@ -62,6 +62,7 @@ const MAX_LINE_LENGTH = 2000; // extra SGR bytes into a full-screen redraw and corrupt xterm's cursor state. const TUI_SEQUENCE = /\x1b\[(?:[\d;]*[ABCDEFGHJKST]|\?[\d;]*[hl])/; const TUI_FRAME_SEQUENCE = /[\u2500-\u257f]|\x1b[()][0B]|\x1b\[[0-9;]*[~`]/; +const CONTROL_STRING_SEQUENCE = /\x1b[\]P^_]/; // A bare \r (not immediately followed by \n) means the terminal is overwriting // the current line (shell prompts, progress bars). Highlighting mid-rewrite @@ -400,6 +401,7 @@ export function highlightTerminalOutput( if (TUI_SEQUENCE.test(text)) return text; if (TUI_FRAME_SEQUENCE.test(text)) return text; + if (CONTROL_STRING_SEQUENCE.test(text)) return text; if (MID_LINE_CR.test(text)) return text; const activePatterns = buildActivePatterns(options);