2
2
3
3
import click
4
4
import sys
5
- from prompt_toolkit import PromptSession
6
5
from prompt_toolkit .history import InMemoryHistory
7
6
8
7
from ._completer import ClickCompleter
9
8
from .exceptions import ClickExit # type: ignore[attr-defined]
10
9
from .exceptions import CommandLineParserError , ExitReplException , InvalidGroupFormat
11
10
from .utils import _execute_internal_and_sys_cmds
11
+ from .core import ReplContext
12
+ from .globals_ import ISATTY , get_current_repl_ctx
12
13
13
14
14
15
__all__ = ["bootstrap_prompt" , "register_repl" , "repl" ]
@@ -73,8 +74,6 @@ def repl(
73
74
f"an optional argument '{ param .name } ' in REPL mode"
74
75
)
75
76
76
- isatty = sys .stdin .isatty ()
77
-
78
77
# Delete the REPL command from those available, as we don't want to allow
79
78
# nesting REPLs (note: pass `None` to `pop` as we don't want to error if
80
79
# REPL command already not present for some reason).
@@ -90,58 +89,67 @@ def repl(
90
89
91
90
original_command = available_commands .pop (repl_command_name , None )
92
91
93
- if isatty :
94
- prompt_kwargs = bootstrap_prompt (group , prompt_kwargs , group_ctx )
95
- session = PromptSession (** prompt_kwargs )
92
+ repl_ctx = ReplContext (
93
+ group_ctx ,
94
+ bootstrap_prompt (group , prompt_kwargs , group_ctx ),
95
+ get_current_repl_ctx (silent = True ),
96
+ )
96
97
97
- def get_command ():
98
- return session .prompt ()
98
+ if ISATTY :
99
+ # If stdin is a TTY, prompt the user for input using PromptSession.
100
+ def get_command () -> str :
101
+ return repl_ctx .session .prompt () # type: ignore
99
102
100
103
else :
101
- get_command = sys .stdin .readline
102
-
103
- while True :
104
- try :
105
- command = get_command ()
106
- except KeyboardInterrupt :
107
- continue
108
- except EOFError :
109
- break
110
-
111
- if not command :
112
- if isatty :
104
+ # If stdin is not a TTY, read input from stdin directly.
105
+ def get_command () -> str :
106
+ inp = sys .stdin .readline ().strip ()
107
+ repl_ctx ._history .append (inp )
108
+ return inp
109
+
110
+ with repl_ctx :
111
+ while True :
112
+ try :
113
+ command = get_command ()
114
+ except KeyboardInterrupt :
113
115
continue
114
- else :
116
+ except EOFError :
115
117
break
116
118
117
- try :
118
- args = _execute_internal_and_sys_cmds (
119
- command , allow_internal_commands , allow_system_commands
120
- )
121
- if args is None :
122
- continue
119
+ if not command :
120
+ if ISATTY :
121
+ continue
122
+ else :
123
+ break
123
124
124
- except CommandLineParserError :
125
- continue
125
+ try :
126
+ args = _execute_internal_and_sys_cmds (
127
+ command , allow_internal_commands , allow_system_commands
128
+ )
129
+ if args is None :
130
+ continue
126
131
127
- except ExitReplException :
128
- break
132
+ except CommandLineParserError :
133
+ continue
134
+
135
+ except ExitReplException :
136
+ break
129
137
130
- try :
131
- # The group command will dispatch based on args.
132
- old_protected_args = group_ctx .protected_args
133
138
try :
134
- group_ctx .protected_args = args
135
- group .invoke (group_ctx )
136
- finally :
137
- group_ctx .protected_args = old_protected_args
138
- except click .ClickException as e :
139
- e .show ()
140
- except (ClickExit , SystemExit ):
141
- pass
142
-
143
- except ExitReplException :
144
- break
139
+ # The group command will dispatch based on args.
140
+ old_protected_args = group_ctx .protected_args
141
+ try :
142
+ group_ctx .protected_args = args
143
+ group .invoke (group_ctx )
144
+ finally :
145
+ group_ctx .protected_args = old_protected_args
146
+ except click .ClickException as e :
147
+ e .show ()
148
+ except (ClickExit , SystemExit ):
149
+ pass
150
+
151
+ except ExitReplException :
152
+ break
145
153
146
154
if original_command is not None :
147
155
available_commands [repl_command_name ] = original_command
0 commit comments