##// END OF EJS Templates
Merge pull request #10479 from memeplex/pdbstyle...
Thomas Kluyver -
r23572:075c197e merge
parent child Browse files
Show More
@@ -1,123 +1,124 b''
1 1 import signal
2 2 import sys
3 3
4 4 from IPython.core.debugger import Pdb
5 5
6 6 from IPython.core.completer import IPCompleter
7 7 from .ptutils import IPythonPTCompleter
8 8 from .shortcuts import suspend_to_bg, cursor_in_leading_ws
9 9
10 10 from prompt_toolkit.enums import DEFAULT_BUFFER
11 11 from prompt_toolkit.filters import (Condition, HasFocus, HasSelection,
12 12 ViInsertMode, EmacsInsertMode)
13 13 from prompt_toolkit.keys import Keys
14 14 from prompt_toolkit.key_binding.manager import KeyBindingManager
15 15 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
16 16 from prompt_toolkit.token import Token
17 17 from prompt_toolkit.shortcuts import create_prompt_application
18 18 from prompt_toolkit.interface import CommandLineInterface
19 19 from prompt_toolkit.enums import EditingMode
20 20
21 21
22 22 class TerminalPdb(Pdb):
23 23 def __init__(self, *args, **kwargs):
24 24 Pdb.__init__(self, *args, **kwargs)
25 25 self._ptcomp = None
26 26 self.pt_init()
27 27
28 28 def pt_init(self):
29 29 def get_prompt_tokens(cli):
30 30 return [(Token.Prompt, self.prompt)]
31 31
32 32 def patch_stdout(**kwargs):
33 33 return self.pt_cli.patch_stdout_context(**kwargs)
34 34
35 35 if self._ptcomp is None:
36 36 compl = IPCompleter(shell=self.shell,
37 37 namespace={},
38 38 global_namespace={},
39 39 parent=self.shell,
40 40 )
41 41 self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout)
42 42
43 43 kbmanager = KeyBindingManager.for_prompt()
44 44 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
45 45 kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend
46 46 )(suspend_to_bg)
47 47
48 48 if self.shell.display_completions == 'readlinelike':
49 49 kbmanager.registry.add_binding(Keys.ControlI,
50 50 filter=(HasFocus(DEFAULT_BUFFER)
51 51 & ~HasSelection()
52 52 & ViInsertMode() | EmacsInsertMode()
53 53 & ~cursor_in_leading_ws
54 54 ))(display_completions_like_readline)
55 55 multicolumn = (self.shell.display_completions == 'multicolumn')
56 56
57 57 self._pt_app = create_prompt_application(
58 58 editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()),
59 59 key_bindings_registry=kbmanager.registry,
60 60 history=self.shell.debugger_history,
61 61 completer= self._ptcomp,
62 62 enable_history_search=True,
63 63 mouse_support=self.shell.mouse_support,
64 64 get_prompt_tokens=get_prompt_tokens,
65 65 display_completions_in_columns=multicolumn,
66 style=self.shell.style
66 67 )
67 68 self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
68 69
69 70 def cmdloop(self, intro=None):
70 71 """Repeatedly issue a prompt, accept input, parse an initial prefix
71 72 off the received input, and dispatch to action methods, passing them
72 73 the remainder of the line as argument.
73 74
74 75 override the same methods from cmd.Cmd to provide prompt toolkit replacement.
75 76 """
76 77 if not self.use_rawinput:
77 78 raise ValueError('Sorry ipdb does not support use_rawinput=False')
78 79
79 80 self.preloop()
80 81
81 82 try:
82 83 if intro is not None:
83 84 self.intro = intro
84 85 if self.intro:
85 86 self.stdout.write(str(self.intro)+"\n")
86 87 stop = None
87 88 while not stop:
88 89 if self.cmdqueue:
89 90 line = self.cmdqueue.pop(0)
90 91 else:
91 92 self._ptcomp.ipy_completer.namespace = self.curframe_locals
92 93 self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals
93 94 try:
94 95 line = self.pt_cli.run(reset_current_buffer=True).text
95 96 except EOFError:
96 97 line = 'EOF'
97 98 line = self.precmd(line)
98 99 stop = self.onecmd(line)
99 100 stop = self.postcmd(stop, line)
100 101 self.postloop()
101 102 except Exception:
102 103 raise
103 104
104 105
105 106 def set_trace(frame=None):
106 107 """
107 108 Start debugging from `frame`.
108 109
109 110 If frame is not specified, debugging starts from caller's frame.
110 111 """
111 112 TerminalPdb().set_trace(frame or sys._getframe().f_back)
112 113
113 114
114 115 if __name__ == '__main__':
115 116 import pdb
116 117 # IPython.core.debugger.Pdb.trace_dispatch shall not catch
117 118 # bdb.BdbQuit. When started through __main__ and an exception
118 119 # happened after hitting "c", this is needed in order to
119 120 # be able to quit the debugging session (see #9950).
120 121 old_trace_dispatch = pdb.Pdb.trace_dispatch
121 122 pdb.Pdb = TerminalPdb
122 123 pdb.Pdb.trace_dispatch = old_trace_dispatch
123 124 pdb.main()
@@ -1,516 +1,516 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2
3 3 import os
4 4 import sys
5 5 import warnings
6 6 from warnings import warn
7 7
8 8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
9 9 from IPython.utils import io
10 10 from IPython.utils.py3compat import cast_unicode_py2, input
11 11 from IPython.utils.terminal import toggle_set_term_title, set_term_title
12 12 from IPython.utils.process import abbrev_cwd
13 13 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union
14 14
15 15 from prompt_toolkit.document import Document
16 16 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
17 17 from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
18 18 from prompt_toolkit.history import InMemoryHistory
19 19 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
20 20 from prompt_toolkit.interface import CommandLineInterface
21 21 from prompt_toolkit.key_binding.manager import KeyBindingManager
22 22 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
23 23 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
24 24
25 25 from pygments.styles import get_style_by_name, get_all_styles
26 26 from pygments.style import Style
27 27 from pygments.token import Token
28 28
29 29 from .debugger import TerminalPdb, Pdb
30 30 from .magics import TerminalMagics
31 31 from .pt_inputhooks import get_inputhook_name_and_func
32 32 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
33 33 from .ptutils import IPythonPTCompleter, IPythonPTLexer
34 34 from .shortcuts import register_ipython_shortcuts
35 35
36 36 DISPLAY_BANNER_DEPRECATED = object()
37 37
38 38
39 39 class _NoStyle(Style): pass
40 40
41 41
42 42
43 43 _style_overrides_light_bg = {
44 44 Token.Prompt: '#0000ff',
45 45 Token.PromptNum: '#0000ee bold',
46 46 Token.OutPrompt: '#cc0000',
47 47 Token.OutPromptNum: '#bb0000 bold',
48 48 }
49 49
50 50 _style_overrides_linux = {
51 51 Token.Prompt: '#00cc00',
52 52 Token.PromptNum: '#00bb00 bold',
53 53 Token.OutPrompt: '#cc0000',
54 54 Token.OutPromptNum: '#bb0000 bold',
55 55 }
56 56
57 57
58 58
59 59 def get_default_editor():
60 60 try:
61 61 return os.environ['EDITOR']
62 62 except KeyError:
63 63 pass
64 64 except UnicodeError:
65 65 warn("$EDITOR environment variable is not pure ASCII. Using platform "
66 66 "default editor.")
67 67
68 68 if os.name == 'posix':
69 69 return 'vi' # the only one guaranteed to be there!
70 70 else:
71 71 return 'notepad' # same in Windows!
72 72
73 73 # conservatively check for tty
74 74 # overridden streams can result in things like:
75 75 # - sys.stdin = None
76 76 # - no isatty method
77 77 for _name in ('stdin', 'stdout', 'stderr'):
78 78 _stream = getattr(sys, _name)
79 79 if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
80 80 _is_tty = False
81 81 break
82 82 else:
83 83 _is_tty = True
84 84
85 85
86 86 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
87 87
88 88 class TerminalInteractiveShell(InteractiveShell):
89 89 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
90 90 'to reserve for the completion menu'
91 91 ).tag(config=True)
92 92
93 93 def _space_for_menu_changed(self, old, new):
94 94 self._update_layout()
95 95
96 96 pt_cli = None
97 97 debugger_history = None
98 98 _pt_app = None
99 99
100 100 simple_prompt = Bool(_use_simple_prompt,
101 101 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
102 102
103 103 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
104 104 IPython own testing machinery, and emacs inferior-shell integration through elpy.
105 105
106 106 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
107 107 environment variable is set, or the current terminal is not a tty."""
108 108 ).tag(config=True)
109 109
110 110 @property
111 111 def debugger_cls(self):
112 112 return Pdb if self.simple_prompt else TerminalPdb
113 113
114 114 confirm_exit = Bool(True,
115 115 help="""
116 116 Set to confirm when you try to exit IPython with an EOF (Control-D
117 117 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
118 118 you can force a direct exit without any confirmation.""",
119 119 ).tag(config=True)
120 120
121 121 editing_mode = Unicode('emacs',
122 122 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
123 123 ).tag(config=True)
124 124
125 125 mouse_support = Bool(False,
126 126 help="Enable mouse support in the prompt"
127 127 ).tag(config=True)
128 128
129 129 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
130 130 help="""The name or class of a Pygments style to use for syntax
131 131 highlighting: \n %s""" % ', '.join(get_all_styles())
132 132 ).tag(config=True)
133 133
134 134
135 135 @observe('highlighting_style')
136 136 @observe('colors')
137 137 def _highlighting_style_changed(self, change):
138 138 self.refresh_style()
139 139
140 140 def refresh_style(self):
141 141 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
142 142
143 143
144 144 highlighting_style_overrides = Dict(
145 145 help="Override highlighting format for specific tokens"
146 146 ).tag(config=True)
147 147
148 148 true_color = Bool(False,
149 149 help=("Use 24bit colors instead of 256 colors in prompt highlighting. "
150 150 "If your terminal supports true color, the following command "
151 151 "should print 'TRUECOLOR' in orange: "
152 152 "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")
153 153 ).tag(config=True)
154 154
155 155 editor = Unicode(get_default_editor(),
156 156 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
157 157 ).tag(config=True)
158 158
159 159 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
160 160
161 161 prompts = Instance(Prompts)
162 162
163 163 @default('prompts')
164 164 def _prompts_default(self):
165 165 return self.prompts_class(self)
166 166
167 167 @observe('prompts')
168 168 def _(self, change):
169 169 self._update_layout()
170 170
171 171 @default('displayhook_class')
172 172 def _displayhook_class_default(self):
173 173 return RichPromptDisplayHook
174 174
175 175 term_title = Bool(True,
176 176 help="Automatically set the terminal title"
177 177 ).tag(config=True)
178 178
179 179 display_completions = Enum(('column', 'multicolumn','readlinelike'),
180 180 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
181 181 "'readlinelike'. These options are for `prompt_toolkit`, see "
182 182 "`prompt_toolkit` documentation for more information."
183 183 ),
184 184 default_value='multicolumn').tag(config=True)
185 185
186 186 highlight_matching_brackets = Bool(True,
187 187 help="Highlight matching brackets.",
188 188 ).tag(config=True)
189 189
190 190 extra_open_editor_shortcuts = Bool(False,
191 191 help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. "
192 192 "This is in addition to the F2 binding, which is always enabled."
193 193 ).tag(config=True)
194 194
195 195 @observe('term_title')
196 196 def init_term_title(self, change=None):
197 197 # Enable or disable the terminal title.
198 198 if self.term_title:
199 199 toggle_set_term_title(True)
200 200 set_term_title('IPython: ' + abbrev_cwd())
201 201 else:
202 202 toggle_set_term_title(False)
203 203
204 204 def init_display_formatter(self):
205 205 super(TerminalInteractiveShell, self).init_display_formatter()
206 206 # terminal only supports plain text
207 207 self.display_formatter.active_types = ['text/plain']
208 208 # disable `_ipython_display_`
209 209 self.display_formatter.ipython_display_formatter.enabled = False
210 210
211 211 def init_prompt_toolkit_cli(self):
212 212 if self.simple_prompt:
213 213 # Fall back to plain non-interactive output for tests.
214 214 # This is very limited, and only accepts a single line.
215 215 def prompt():
216 216 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
217 217 self.prompt_for_code = prompt
218 218 return
219 219
220 220 # Set up keyboard shortcuts
221 221 kbmanager = KeyBindingManager.for_prompt(
222 222 enable_open_in_editor=self.extra_open_editor_shortcuts,
223 223 )
224 224 register_ipython_shortcuts(kbmanager.registry, self)
225 225
226 226 # Pre-populate history from IPython's history database
227 227 history = InMemoryHistory()
228 228 last_cell = u""
229 229 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
230 230 include_latest=True):
231 231 # Ignore blank lines and consecutive duplicates
232 232 cell = cell.rstrip()
233 233 if cell and (cell != last_cell):
234 234 history.append(cell)
235 235 last_cell = cell
236 236
237 237 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
238 style = DynamicStyle(lambda: self._style)
238 self.style = DynamicStyle(lambda: self._style)
239 239
240 240 editing_mode = getattr(EditingMode, self.editing_mode.upper())
241 241
242 242 def patch_stdout(**kwargs):
243 243 return self.pt_cli.patch_stdout_context(**kwargs)
244 244
245 245 self._pt_app = create_prompt_application(
246 246 editing_mode=editing_mode,
247 247 key_bindings_registry=kbmanager.registry,
248 248 history=history,
249 249 completer=IPythonPTCompleter(shell=self,
250 250 patch_stdout=patch_stdout),
251 251 enable_history_search=True,
252 style=style,
252 style=self.style,
253 253 mouse_support=self.mouse_support,
254 254 **self._layout_options()
255 255 )
256 256 self._eventloop = create_eventloop(self.inputhook)
257 257 self.pt_cli = CommandLineInterface(
258 258 self._pt_app, eventloop=self._eventloop,
259 259 output=create_output(true_color=self.true_color))
260 260
261 261 def _make_style_from_name_or_cls(self, name_or_cls):
262 262 """
263 263 Small wrapper that make an IPython compatible style from a style name
264 264
265 265 We need that to add style for prompt ... etc.
266 266 """
267 267 style_overrides = {}
268 268 if name_or_cls == 'legacy':
269 269 legacy = self.colors.lower()
270 270 if legacy == 'linux':
271 271 style_cls = get_style_by_name('monokai')
272 272 style_overrides = _style_overrides_linux
273 273 elif legacy == 'lightbg':
274 274 style_overrides = _style_overrides_light_bg
275 275 style_cls = get_style_by_name('pastie')
276 276 elif legacy == 'neutral':
277 277 # The default theme needs to be visible on both a dark background
278 278 # and a light background, because we can't tell what the terminal
279 279 # looks like. These tweaks to the default theme help with that.
280 280 style_cls = get_style_by_name('default')
281 281 style_overrides.update({
282 282 Token.Number: '#007700',
283 283 Token.Operator: 'noinherit',
284 284 Token.String: '#BB6622',
285 285 Token.Name.Function: '#2080D0',
286 286 Token.Name.Class: 'bold #2080D0',
287 287 Token.Name.Namespace: 'bold #2080D0',
288 288 Token.Prompt: '#009900',
289 289 Token.PromptNum: '#00ff00 bold',
290 290 Token.OutPrompt: '#990000',
291 291 Token.OutPromptNum: '#ff0000 bold',
292 292 })
293 293
294 294 # Hack: Due to limited color support on the Windows console
295 295 # the prompt colors will be wrong without this
296 296 if os.name == 'nt':
297 297 style_overrides.update({
298 298 Token.Prompt: '#ansidarkgreen',
299 299 Token.PromptNum: '#ansigreen bold',
300 300 Token.OutPrompt: '#ansidarkred',
301 301 Token.OutPromptNum: '#ansired bold',
302 302 })
303 303 elif legacy =='nocolor':
304 304 style_cls=_NoStyle
305 305 style_overrides = {}
306 306 else :
307 307 raise ValueError('Got unknown colors: ', legacy)
308 308 else :
309 309 if isinstance(name_or_cls, str):
310 310 style_cls = get_style_by_name(name_or_cls)
311 311 else:
312 312 style_cls = name_or_cls
313 313 style_overrides = {
314 314 Token.Prompt: '#009900',
315 315 Token.PromptNum: '#00ff00 bold',
316 316 Token.OutPrompt: '#990000',
317 317 Token.OutPromptNum: '#ff0000 bold',
318 318 }
319 319 style_overrides.update(self.highlighting_style_overrides)
320 320 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
321 321 style_dict=style_overrides)
322 322
323 323 return style
324 324
325 325 def _layout_options(self):
326 326 """
327 327 Return the current layout option for the current Terminal InteractiveShell
328 328 """
329 329 return {
330 330 'lexer':IPythonPTLexer(),
331 331 'reserve_space_for_menu':self.space_for_menu,
332 332 'get_prompt_tokens':self.prompts.in_prompt_tokens,
333 333 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
334 334 'multiline':True,
335 335 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
336 336
337 337 # Highlight matching brackets, but only when this setting is
338 338 # enabled, and only when the DEFAULT_BUFFER has the focus.
339 339 'extra_input_processors': [ConditionalProcessor(
340 340 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
341 341 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
342 342 Condition(lambda cli: self.highlight_matching_brackets))],
343 343 }
344 344
345 345 def _update_layout(self):
346 346 """
347 347 Ask for a re computation of the application layout, if for example ,
348 348 some configuration options have changed.
349 349 """
350 350 if self._pt_app:
351 351 self._pt_app.layout = create_prompt_layout(**self._layout_options())
352 352
353 353 def prompt_for_code(self):
354 354 document = self.pt_cli.run(
355 355 pre_run=self.pre_prompt, reset_current_buffer=True)
356 356 return document.text
357 357
358 358 def enable_win_unicode_console(self):
359 359 if sys.version_info >= (3, 6):
360 360 # Since PEP 528, Python uses the unicode APIs for the Windows
361 361 # console by default, so WUC shouldn't be needed.
362 362 return
363 363
364 364 import win_unicode_console
365 365 win_unicode_console.enable()
366 366
367 367 def init_io(self):
368 368 if sys.platform not in {'win32', 'cli'}:
369 369 return
370 370
371 371 self.enable_win_unicode_console()
372 372
373 373 import colorama
374 374 colorama.init()
375 375
376 376 # For some reason we make these wrappers around stdout/stderr.
377 377 # For now, we need to reset them so all output gets coloured.
378 378 # https://github.com/ipython/ipython/issues/8669
379 379 # io.std* are deprecated, but don't show our own deprecation warnings
380 380 # during initialization of the deprecated API.
381 381 with warnings.catch_warnings():
382 382 warnings.simplefilter('ignore', DeprecationWarning)
383 383 io.stdout = io.IOStream(sys.stdout)
384 384 io.stderr = io.IOStream(sys.stderr)
385 385
386 386 def init_magics(self):
387 387 super(TerminalInteractiveShell, self).init_magics()
388 388 self.register_magics(TerminalMagics)
389 389
390 390 def init_alias(self):
391 391 # The parent class defines aliases that can be safely used with any
392 392 # frontend.
393 393 super(TerminalInteractiveShell, self).init_alias()
394 394
395 395 # Now define aliases that only make sense on the terminal, because they
396 396 # need direct access to the console in a way that we can't emulate in
397 397 # GUI or web frontend
398 398 if os.name == 'posix':
399 399 for cmd in ['clear', 'more', 'less', 'man']:
400 400 self.alias_manager.soft_define_alias(cmd, cmd)
401 401
402 402
403 403 def __init__(self, *args, **kwargs):
404 404 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
405 405 self.init_prompt_toolkit_cli()
406 406 self.init_term_title()
407 407 self.keep_running = True
408 408
409 409 self.debugger_history = InMemoryHistory()
410 410
411 411 def ask_exit(self):
412 412 self.keep_running = False
413 413
414 414 rl_next_input = None
415 415
416 416 def pre_prompt(self):
417 417 if self.rl_next_input:
418 418 # We can't set the buffer here, because it will be reset just after
419 419 # this. Adding a callable to pre_run_callables does what we need
420 420 # after the buffer is reset.
421 421 s = cast_unicode_py2(self.rl_next_input)
422 422 def set_doc():
423 423 self.pt_cli.application.buffer.document = Document(s)
424 424 if hasattr(self.pt_cli, 'pre_run_callables'):
425 425 self.pt_cli.pre_run_callables.append(set_doc)
426 426 else:
427 427 # Older version of prompt_toolkit; it's OK to set the document
428 428 # directly here.
429 429 set_doc()
430 430 self.rl_next_input = None
431 431
432 432 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
433 433
434 434 if display_banner is not DISPLAY_BANNER_DEPRECATED:
435 435 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
436 436
437 437 self.keep_running = True
438 438 while self.keep_running:
439 439 print(self.separate_in, end='')
440 440
441 441 try:
442 442 code = self.prompt_for_code()
443 443 except EOFError:
444 444 if (not self.confirm_exit) \
445 445 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
446 446 self.ask_exit()
447 447
448 448 else:
449 449 if code:
450 450 self.run_cell(code, store_history=True)
451 451
452 452 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
453 453 # An extra layer of protection in case someone mashing Ctrl-C breaks
454 454 # out of our internal code.
455 455 if display_banner is not DISPLAY_BANNER_DEPRECATED:
456 456 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
457 457 while True:
458 458 try:
459 459 self.interact()
460 460 break
461 461 except KeyboardInterrupt as e:
462 462 print("\n%s escaped interact()\n" % type(e).__name__)
463 463 finally:
464 464 # An interrupt during the eventloop will mess up the
465 465 # internal state of the prompt_toolkit library.
466 466 # Stopping the eventloop fixes this, see
467 467 # https://github.com/ipython/ipython/pull/9867
468 468 if hasattr(self, '_eventloop'):
469 469 self._eventloop.stop()
470 470
471 471 _inputhook = None
472 472 def inputhook(self, context):
473 473 if self._inputhook is not None:
474 474 self._inputhook(context)
475 475
476 476 active_eventloop = None
477 477 def enable_gui(self, gui=None):
478 478 if gui:
479 479 self.active_eventloop, self._inputhook =\
480 480 get_inputhook_name_and_func(gui)
481 481 else:
482 482 self.active_eventloop = self._inputhook = None
483 483
484 484 # Run !system commands directly, not through pipes, so terminal programs
485 485 # work correctly.
486 486 system = InteractiveShell.system_raw
487 487
488 488 def auto_rewrite_input(self, cmd):
489 489 """Overridden from the parent class to use fancy rewriting prompt"""
490 490 if not self.show_rewritten_input:
491 491 return
492 492
493 493 tokens = self.prompts.rewrite_prompt_tokens()
494 494 if self.pt_cli:
495 495 self.pt_cli.print_tokens(tokens)
496 496 print(cmd)
497 497 else:
498 498 prompt = ''.join(s for t, s in tokens)
499 499 print(prompt, cmd, sep='')
500 500
501 501 _prompts_before = None
502 502 def switch_doctest_mode(self, mode):
503 503 """Switch prompts to classic for %doctest_mode"""
504 504 if mode:
505 505 self._prompts_before = self.prompts
506 506 self.prompts = ClassicPrompts(self)
507 507 elif self._prompts_before:
508 508 self.prompts = self._prompts_before
509 509 self._prompts_before = None
510 510 self._update_layout()
511 511
512 512
513 513 InteractiveShellABC.register(TerminalInteractiveShell)
514 514
515 515 if __name__ == '__main__':
516 516 TerminalInteractiveShell.instance().interact()
General Comments 0
You need to be logged in to leave comments. Login now