diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 3042ffb7a309..32498a60e624 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,5 +1,6 @@ import platform import sys +from enum import Enum if sys.platform != "win32": import readline @@ -8,6 +9,20 @@ is_wsl = "microsoft-standard-WSL" in platform.release() +class ShellIntegrationSequence(str, Enum): + SOH = "\001" + STX = "\002" + COMMAND_EXECUTED = "\x1b]633;C\x07" + COMMAND_LINE = "\x1b]633;E;" + COMMAND_FINISHED = "\x1b]633;D;" + PROMPT_STARTED = "\x1b]633;A\x07" + COMMAND_START = "\x1b]633;B\x07" + TERMINATOR = "\x07" + + def __str__(self): + return self.value + + class REPLHooks: def __init__(self): self.global_exit = None @@ -53,26 +68,30 @@ def __str__(self): # For non-windows allow recent_command history. if sys.platform != "win32": result = "{soh}{command_executed}{command_line}{command_finished}{prompt_started}{stx}{prompt}{soh}{command_start}{stx}".format( - soh="\001", - stx="\002", - command_executed="\x1b]633;C\x07", - command_line="\x1b]633;E;" + str(get_last_command()) + "\x07", - command_finished="\x1b]633;D;" + str(exit_code) + "\x07", - prompt_started="\x1b]633;A\x07", + soh=ShellIntegrationSequence.SOH, + stx=ShellIntegrationSequence.STX, + command_executed=ShellIntegrationSequence.COMMAND_EXECUTED, + command_line=ShellIntegrationSequence.COMMAND_LINE + + str(get_last_command()) + + ShellIntegrationSequence.TERMINATOR, + command_finished=ShellIntegrationSequence.COMMAND_FINISHED + + str(exit_code) + + ShellIntegrationSequence.TERMINATOR, + prompt_started=ShellIntegrationSequence.PROMPT_STARTED, prompt=original_ps1, - command_start="\x1b]633;B\x07", + command_start=ShellIntegrationSequence.COMMAND_START, ) else: result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format( - command_finished="\x1b]633;D;" + str(exit_code) + "\x07", - prompt_started="\x1b]633;A\x07", + command_finished=ShellIntegrationSequence.COMMAND_FINISHED + + str(exit_code) + + ShellIntegrationSequence.TERMINATOR, + prompt_started=ShellIntegrationSequence.PROMPT_STARTED, prompt=original_ps1, - command_start="\x1b]633;B\x07", - command_executed="\x1b]633;C\x07", + command_start=ShellIntegrationSequence.COMMAND_START, + command_executed=ShellIntegrationSequence.COMMAND_EXECUTED, ) - # result = f"{chr(27)}]633;D;{exit_code}{chr(7)}{chr(27)}]633;A{chr(7)}{original_ps1}{chr(27)}]633;B{chr(7)}{chr(27)}]633;C{chr(7)}" - return result def __repr__(self): @@ -83,6 +102,6 @@ def __repr__(self): sys.ps1 = PS1() if sys.platform == "darwin": - print("Cmd click to launch VS Code Native REPL") + print("Cmd click to launch VS Code Native REPL (https://aka.ms/python-native-repl)") else: - print("Ctrl click to launch VS Code Native REPL") + print("Ctrl click to launch VS Code Native REPL (https://aka.ms/python-native-repl)") diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index 7503a725b6d1..013aa3d514b5 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -70,7 +70,9 @@ def test_print_statement_darwin(monkeypatch): with monkeypatch.context() as m: m.setattr("builtins.print", Mock()) importlib.reload(sys.modules["pythonrc"]) - print.assert_any_call("Cmd click to launch VS Code Native REPL") + print.assert_any_call( + "Cmd click to launch VS Code Native REPL (https://aka.ms/python-native-repl)" + ) if sys.platform == "win32": @@ -80,4 +82,6 @@ def test_print_statement_non_darwin(monkeypatch): with monkeypatch.context() as m: m.setattr("builtins.print", Mock()) importlib.reload(sys.modules["pythonrc"]) - print.assert_any_call("Ctrl click to launch VS Code Native REPL") + print.assert_any_call( + "Ctrl click to launch VS Code Native REPL (https://aka.ms/python-native-repl)" + ) diff --git a/src/client/terminals/pythonStartupLinkProvider.ts b/src/client/terminals/pythonStartupLinkProvider.ts index aba1270f1412..6e7234c4687b 100644 --- a/src/client/terminals/pythonStartupLinkProvider.ts +++ b/src/client/terminals/pythonStartupLinkProvider.ts @@ -21,13 +21,10 @@ export class CustomTerminalLinkProvider implements TerminalLinkProvider { const links: CustomTerminalLink[] = []; - let expectedNativeLink; - - if (process.platform === 'darwin') { - expectedNativeLink = 'Cmd click to launch VS Code Native REPL'; - } else { - expectedNativeLink = 'Ctrl click to launch VS Code Native REPL'; - } + let expectedNativeLink = + process.platform === 'darwin' + ? 'Cmd click to launch VS Code Native REPL' + : 'Ctrl click to launch VS Code Native REPL'; if (context.line.includes(expectedNativeLink)) { links.push({ diff --git a/src/test/terminals/shellIntegration/pythonStartup.test.ts b/src/test/terminals/shellIntegration/pythonStartup.test.ts index 16f45fb26a40..f15da1179018 100644 --- a/src/test/terminals/shellIntegration/pythonStartup.test.ts +++ b/src/test/terminals/shellIntegration/pythonStartup.test.ts @@ -182,7 +182,8 @@ suite('Terminal - Shell Integration with PYTHONSTARTUP', () => { test('Mac - Verify provideTerminalLinks returns links when context.line contains expectedNativeLink', () => { const provider = new CustomTerminalLinkProvider(); const context: TerminalLinkContext = { - line: 'Some random string with Cmd click to launch VS Code Native REPL', + line: + 'Some random string with Cmd click to launch VS Code Native REPL (https://aka.ms/python-native-repl)', terminal: {} as Terminal, }; const token: CancellationToken = { @@ -224,7 +225,8 @@ suite('Terminal - Shell Integration with PYTHONSTARTUP', () => { test('Windows/Linux - Verify provideTerminalLinks returns links when context.line contains expectedNativeLink', () => { const provider = new CustomTerminalLinkProvider(); const context: TerminalLinkContext = { - line: 'Some random string with Ctrl click to launch VS Code Native REPL', + line: + 'Some random string with Ctrl click to launch VS Code Native REPL (https://aka.ms/python-native-repl)', terminal: {} as Terminal, }; const token: CancellationToken = {