Skip to content

Commit a3feed7

Browse files
committed
Use removeAnsiEscapeCodes and bring back $ in prompt regex
1 parent b4579f3 commit a3feed7

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/features/terminal/utils.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,38 +69,39 @@ export async function waitForShellIntegration(terminal: Terminal): Promise<boole
6969

7070
// Detects if the given text content appears to end with a common prompt pattern.
7171
function detectsCommonPromptPattern(terminalData: string): boolean {
72+
const sanitizedTerminalData = removeAnsiEscapeCodes(terminalData);
7273
// PowerShell prompt: PS C:\> or similar patterns
73-
if (/PS\s+[A-Z]:\\.*>\s*/.test(terminalData)) {
74+
if (/PS\s+[A-Z]:\\.*>\s*$/.test(sanitizedTerminalData)) {
7475
return true;
7576
}
7677

7778
// Command Prompt: C:\path>
78-
if (/^[A-Z]:\\.*>\s*/.test(terminalData)) {
79+
if (/^[A-Z]:\\.*>\s*$/.test(sanitizedTerminalData)) {
7980
return true;
8081
}
8182

8283
// Bash-style prompts ending with $
83-
if (/\$\s*/.test(terminalData)) {
84+
if (/\$\s*$/.test(sanitizedTerminalData)) {
8485
return true;
8586
}
8687

8788
// Root prompts ending with #
88-
if (/#\s*/.test(terminalData)) {
89+
if (/#\s*$/.test(sanitizedTerminalData)) {
8990
return true;
9091
}
9192

9293
// Python REPL prompt
93-
if (/^>>>\s*/.test(terminalData)) {
94+
if (/^>>>\s*$/.test(sanitizedTerminalData)) {
9495
return true;
9596
}
9697

9798
// Custom prompts ending with the starship character (\u276f)
98-
if (/\u276f\s*/.test(terminalData)) {
99+
if (/\u276f\s*$/.test(sanitizedTerminalData)) {
99100
return true;
100101
}
101102

102103
// Generic prompts ending with common prompt characters
103-
if (/[>%]\s*/.test(terminalData)) {
104+
if (/[>%]\s*$/.test(sanitizedTerminalData)) {
104105
return true;
105106
}
106107

@@ -262,3 +263,28 @@ export async function getAllDistinctProjectEnvironments(
262263

263264
return envs.length > 0 ? envs : undefined;
264265
}
266+
267+
// Defacto standard: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
268+
const CSI_SEQUENCE = /(?:\x1b\[|\x9b)[=?>!]?[\d;:]*["$#'* ]?[a-zA-Z@^`{}|~]/;
269+
const OSC_SEQUENCE = /(?:\x1b\]|\x9d).*?(?:\x1b\\|\x07|\x9c)/;
270+
const ESC_SEQUENCE = /\x1b(?:[ #%\(\)\*\+\-\.\/]?[a-zA-Z0-9\|}~@])/;
271+
const CONTROL_SEQUENCES = new RegExp(
272+
'(?:' + [CSI_SEQUENCE.source, OSC_SEQUENCE.source, ESC_SEQUENCE.source].join('|') + ')',
273+
'g',
274+
);
275+
276+
/**
277+
* Strips ANSI escape sequences from a string.
278+
* @param str The dastringa stringo strip the ANSI escape sequences from.
279+
*
280+
* @example
281+
* removeAnsiEscapeCodes('\u001b[31mHello, World!\u001b[0m');
282+
* // 'Hello, World!'
283+
*/
284+
export function removeAnsiEscapeCodes(str: string): string {
285+
if (str) {
286+
str = str.replace(CONTROL_SEQUENCES, '');
287+
}
288+
289+
return str;
290+
}

0 commit comments

Comments
 (0)