Skip to content

Commit d10b2f7

Browse files
authored
Allow run recent command for REPL using shell integration (#22720)
Resolves: #22647 Allow access to recent command "Terminal: Run recent command:" for Python REPL users. Due to GNU readline, Mac and Linux Users will now be able to see their REPL command history. Blocked on recent history support for Windows: - Would have to go through VS Code to pick up the command or via native VS Code REPL.
1 parent 1eaf5a3 commit d10b2f7

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@
16011601
"@types/xml2js": "^0.4.2",
16021602
"@typescript-eslint/eslint-plugin": "^3.7.0",
16031603
"@typescript-eslint/parser": "^3.7.0",
1604-
"@vscode/test-electron": "^2.3.4",
1604+
"@vscode/test-electron": "^2.3.8",
16051605
"@vscode/vsce": "^2.18.0",
16061606
"bent": "^7.3.12",
16071607
"chai": "^4.1.2",
@@ -1643,13 +1643,13 @@
16431643
"typescript": "4.5.5",
16441644
"uuid": "^8.3.2",
16451645
"webpack": "^5.76.0",
1646-
"worker-loader": "^3.0.8",
16471646
"webpack-bundle-analyzer": "^4.5.0",
16481647
"webpack-cli": "^4.9.2",
16491648
"webpack-fix-default-import-plugin": "^1.0.3",
16501649
"webpack-merge": "^5.8.0",
16511650
"webpack-node-externals": "^3.0.0",
16521651
"webpack-require-from": "^1.8.6",
1652+
"worker-loader": "^3.0.8",
16531653
"yargs": "^15.3.1"
16541654
}
16551655
}

pythonFiles/pythonrc.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import sys
22

3+
if sys.platform != "win32":
4+
import readline
5+
36
original_ps1 = ">>> "
47

58

@@ -25,6 +28,15 @@ def my_excepthook(self, type, value, traceback):
2528
self.original_excepthook(type, value, traceback)
2629

2730

31+
def get_last_command():
32+
# Get the last history item
33+
last_command = ""
34+
if sys.platform != "win32":
35+
last_command = readline.get_history_item(readline.get_current_history_length())
36+
37+
return last_command
38+
39+
2840
class ps1:
2941
hooks = repl_hooks()
3042
sys.excepthook = hooks.my_excepthook
@@ -39,14 +51,27 @@ def __str__(self):
3951
exit_code = 0
4052

4153
# Guide following official VS Code doc for shell integration sequence:
42-
# result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
43-
# command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
44-
# prompt_started="\x1b]633;A\x07",
45-
# prompt=original_ps1,
46-
# command_start="\x1b]633;B\x07",
47-
# command_executed="\x1b]633;C\x07",
48-
# )
49-
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)}"
54+
result = ""
55+
# For non-windows allow recent_command history.
56+
if sys.platform != "win32":
57+
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}{command_line}".format(
58+
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
59+
prompt_started="\x1b]633;A\x07",
60+
prompt=original_ps1,
61+
command_start="\x1b]633;B\x07",
62+
command_executed="\x1b]633;C\x07",
63+
command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
64+
)
65+
else:
66+
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
67+
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
68+
prompt_started="\x1b]633;A\x07",
69+
prompt=original_ps1,
70+
command_start="\x1b]633;B\x07",
71+
command_executed="\x1b]633;C\x07",
72+
)
73+
74+
# 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)}"
5075

5176
return result
5277

pythonFiles/tests/test_shell_integration.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import importlib
2+
import sys
23
from unittest.mock import Mock
3-
44
import pythonrc
55

66

@@ -10,7 +10,13 @@ def test_decoration_success():
1010

1111
ps1.hooks.failure_flag = False
1212
result = str(ps1)
13-
assert result == "\x1b]633;D;0\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07"
13+
if sys.platform != "win32":
14+
assert (
15+
result
16+
== "\x1b]633;D;0\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
17+
)
18+
else:
19+
pass
1420

1521

1622
def test_decoration_failure():
@@ -19,8 +25,13 @@ def test_decoration_failure():
1925

2026
ps1.hooks.failure_flag = True
2127
result = str(ps1)
22-
23-
assert result == "\x1b]633;D;1\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07"
28+
if sys.platform != "win32":
29+
assert (
30+
result
31+
== "\x1b]633;D;1\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
32+
)
33+
else:
34+
pass
2435

2536

2637
def test_displayhook_call():

0 commit comments

Comments
 (0)