##// END OF EJS Templates
Fix `help=` is a Constructor arg, not a metadata.
Fix `help=` is a Constructor arg, not a metadata.

File last commit:

r22338:507bdb38
r22338:507bdb38
Show More
ptshell.py
464 lines | 17.2 KiB | text/x-python | PythonLexer
Thomas Kluyver
Python 2.7 support & highlighting in prompt_toolkit interface
r21930 """IPython terminal interface using prompt_toolkit in place of readline"""
from __future__ import print_function
Thomas Kluyver
Restore terminal magics and aliases...
r22128 import os
Thomas Kluyver
Integrate colorama for coloured output on Windows
r21950 import sys
Jonathan Slenders
ControlZ should suspend IPython to the background.
r22194 import signal
Jonathan Slenders
Bugfix: when doing \dot completion. Compose unicode character from completion.
r22227 import unicodedata
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 from warnings import warn
Jonathan Slenders
Bugfix: when doing \dot completion. Compose unicode character from completion.
r22227 from wcwidth import wcwidth
Thomas Kluyver
Integrate colorama for coloured output on Windows
r21950
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 from IPython.core.error import TryNext
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from IPython.core.interactiveshell import InteractiveShell
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
Min RK
support term_title in pt shell...
r22124 from IPython.utils.terminal import toggle_set_term_title, set_term_title
from IPython.utils.process import abbrev_cwd
Matthias Bussonnier
Update `ptshell.py` to use new traitlets API.
r22333 from traitlets import Bool, CBool, Unicode, Dict, Integer, observe
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Add completion support
r21916 from prompt_toolkit.completion import Completer, Completion
Jonathan Slenders
Upgrade to prompt_toolkit 1.0.0.
r22296 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode
from prompt_toolkit.filters import HasFocus, HasSelection, Condition, ViInsertMode, EmacsInsertMode
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 from prompt_toolkit.history import InMemoryHistory
Matthias Bussonnier
Make style and layout dynamic....
r22277 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
Thomas Kluyver
Refine multiline behaviour
r21912 from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.keys import Keys
Jonathan Slenders
Created IPythonPTLexer, which is a wrapper around BashLexer and PythonLexer. (When the input starts with an exclamation mark, use the BashLexer.)
r22197 from prompt_toolkit.layout.lexers import Lexer
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from prompt_toolkit.layout.lexers import PygmentsLexer
Matthias Bussonnier
Make style and layout dynamic....
r22277 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Matthias Bussonnier
Make style and layout dynamic....
r22277 from pygments.styles import get_style_by_name, get_all_styles
Jonathan Slenders
Created IPythonPTLexer, which is a wrapper around BashLexer and PythonLexer. (When the input starts with an exclamation mark, use the BashLexer.)
r22197 from pygments.lexers import Python3Lexer, BashLexer, PythonLexer
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from pygments.token import Token
Thomas Kluyver
Write & borrow some inputhooks for prompt_toolkit
r21934 from .pt_inputhooks import get_inputhook_func
Thomas Kluyver
Restore terminal magics and aliases...
r22128 from .interactiveshell import get_default_editor, TerminalMagics
Thomas Kluyver
Write & borrow some inputhooks for prompt_toolkit
r21934
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Add completion support
r21916 class IPythonPTCompleter(Completer):
"""Adaptor to provide IPython completions to prompt_toolkit"""
def __init__(self, ipy_completer):
self.ipy_completer = ipy_completer
def get_completions(self, document, complete_event):
Thomas Kluyver
Don't try to complete on an empty line
r21922 if not document.current_line.strip():
return
Thomas Kluyver
Add completion support
r21916 used, matches = self.ipy_completer.complete(
line_buffer=document.current_line,
cursor_pos=document.cursor_position_col
)
start_pos = -len(used)
for m in matches:
Jonathan Slenders
Bugfix: when doing \dot completion. Compose unicode character from completion.
r22227 m = unicodedata.normalize('NFC', m)
# When the first character of the completion has a zero length,
# then it's probably a decomposed unicode character. E.g. caused by
# the "\dot" completion. Try to compose again with the previous
# character.
if wcwidth(m[0]) == 0:
if document.cursor_position + start_pos > 0:
char_before = document.text[document.cursor_position + start_pos - 1]
m = unicodedata.normalize('NFC', char_before + m)
# Yield the modified completion instead, if this worked.
if wcwidth(m[0:1]) == 1:
yield Completion(m, start_position=start_pos - 1)
continue
Kelly Liu
Initial patch with Jedi completion (no function header description)....
r22292 # TODO: Use Jedi to determine meta_text
# (Jedi currently has a bug that results in incorrect information.)
# meta_text = ''
# yield Completion(m, start_position=start_pos,
# display_meta=meta_text)
Thomas Kluyver
Add completion support
r21916 yield Completion(m, start_position=start_pos)
Jonathan Slenders
Created IPythonPTLexer, which is a wrapper around BashLexer and PythonLexer. (When the input starts with an exclamation mark, use the BashLexer.)
r22197 class IPythonPTLexer(Lexer):
"""
Wrapper around PythonLexer and BashLexer.
"""
def __init__(self):
self.python_lexer = PygmentsLexer(Python3Lexer if PY3 else PythonLexer)
self.shell_lexer = PygmentsLexer(BashLexer)
def lex_document(self, cli, document):
if document.text.startswith('!'):
return self.shell_lexer.lex_document(cli, document)
else:
return self.python_lexer.lex_document(cli, document)
Thomas Kluyver
Rename PTInteractiveShell to TerminalInteractiveShell...
r22112 class TerminalInteractiveShell(InteractiveShell):
Thomas Kluyver
Turn out prompt & traceback colours on when using prompt_toolkit
r21920 colors_force = True
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
'to reserve for the completion menu'
).tag(config=True)
Matthias Bussonnier
Make "reserve_space_for_menu" configurable....
r22276
Matthias Bussonnier
Make style and layout dynamic....
r22277 def _space_for_menu_changed(self, old, new):
Matthias Bussonnier
Rename relayout to _update_layout
r22279 self._update_layout()
Matthias Bussonnier
Make style and layout dynamic....
r22277
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 pt_cli = None
Matthias Bussonnier
Update `ptshell.py` to use new traitlets API.
r22333 autoedit_syntax = CBool(False).tag(config=True,
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 help="auto editing of files with syntax errors.")
Matthias Bussonnier
Update `ptshell.py` to use new traitlets API.
r22333 confirm_exit = CBool(True).tag(config=True,
Thomas Kluyver
Add and use confirm_exit flag in prompt_toolkit shell...
r22186 help="""
Set to confirm when you try to exit IPython with an EOF (Control-D
in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
you can force a direct exit without any confirmation.""",
)
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 editing_mode = Unicode('emacs',
Thomas Kluyver
Configure editing_mode instead of vi_mode...
r22301 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Thomas Kluyver
Add config option for vi mode
r21928
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 mouse_support = Bool(False,
Thomas Kluyver
Config option to enable mouse support
r22055 help="Enable mouse support in the prompt"
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Thomas Kluyver
Config option to enable mouse support
r22055
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 highlighting_style = Unicode('default',
Matthias Bussonnier
Make style and layout dynamic....
r22277 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Thomas Kluyver
Config options for syntax higlighting style
r21929
Matthias Bussonnier
Make style and layout dynamic....
r22277 def _highlighting_style_changed(self, old, new):
self._style = self._make_style_from_name(self.highlighting_style)
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 highlighting_style_overrides = Dict(
Thomas Kluyver
Config options for syntax higlighting style
r21929 help="Override highlighting format for specific tokens"
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Thomas Kluyver
Config options for syntax higlighting style
r21929
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 editor = Unicode(get_default_editor(),
Thomas Kluyver
Fix %edit - editor attribute was missing
r21969 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Min RK
support term_title in pt shell...
r22124
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 term_title = Bool(True,
Min RK
support term_title in pt shell...
r22124 help="Automatically set the terminal title"
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Jonathan Slenders
Added display_completions_in_columns option.
r22302
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 display_completions_in_columns = Bool(False,
Jonathan Slenders
Added display_completions_in_columns option.
r22302 help="Display a multi column completion menu.",
Matthias Bussonnier
Fix `help=` is a Constructor arg, not a metadata.
r22338 ).tag(config=True)
Jonathan Slenders
Added display_completions_in_columns option.
r22302
Matthias Bussonnier
Update `ptshell.py` to use new traitlets API.
r22333 @observe('term_title')
def _term_title_changed(self, change):
Min RK
support term_title in pt shell...
r22124 self.init_term_title()
def init_term_title(self):
# Enable or disable the terminal title.
if self.term_title:
toggle_set_term_title(True)
set_term_title('IPython: ' + abbrev_cwd())
else:
toggle_set_term_title(False)
Thomas Kluyver
Fix %edit - editor attribute was missing
r21969
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 def get_prompt_tokens(self, cli):
return [
(Token.Prompt, 'In ['),
Thomas Kluyver
Nicer default colours
r21918 (Token.PromptNum, str(self.execution_count)),
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 (Token.Prompt, ']: '),
]
Thomas Kluyver
Add continuation prompts
r21933 def get_continuation_tokens(self, cli, width):
return [
Matthias Bussonnier
'Restore `...:` as continuation prompt '
r22122 (Token.Prompt, (' ' * (width - 5)) + '...: '),
Thomas Kluyver
Add continuation prompts
r21933 ]
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 def init_prompt_toolkit_cli(self):
Thomas Kluyver
Use simplified prompt in test_embed...
r22132 if ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or not sys.stdin.isatty():
# Fall back to plain non-interactive output for tests.
# This is very limited, and only accepts a single line.
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 def prompt():
return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
self.prompt_for_code = prompt
return
Jonathan Slenders
Upgrade to prompt_toolkit 1.0.0.
r22296 kbmanager = KeyBindingManager.for_prompt()
insert_mode = ViInsertMode() | EmacsInsertMode()
Thomas Kluyver
Only use our Enter handling when the default buffer is active...
r21923 # Ctrl+J == Enter, seemingly
@kbmanager.registry.add_binding(Keys.ControlJ,
Thomas Kluyver
Add config option for vi mode
r21928 filter=(HasFocus(DEFAULT_BUFFER)
& ~HasSelection()
& insert_mode
))
Thomas Kluyver
Refine multiline behaviour
r21912 def _(event):
b = event.current_buffer
Thomas Kluyver
Make behaviour more natural with blank lines at the end of input
r22012 d = b.document
if not (d.on_last_line or d.cursor_position_row >= d.line_count
- d.empty_line_count_at_the_end()):
Thomas Kluyver
Refine multiline behaviour
r21912 b.newline()
return
Thomas Kluyver
Make behaviour more natural with blank lines at the end of input
r22012 status, indent = self.input_splitter.check_complete(d.text)
Thomas Kluyver
Refine multiline behaviour
r21912
if (status != 'incomplete') and b.accept_action.is_returnable:
b.accept_action.validate_and_handle(event.cli, b)
else:
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 b.insert_text('\n' + (' ' * (indent or 0)))
Thomas Kluyver
Only handle Ctrl-C when in main input buffer...
r22162 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
Matthias Bussonnier
Do not redefine _, linter complain....
r22332 def _reset_buffer(event):
Thomas Kluyver
Do sensible things on Ctrl-C and Ctrl-D
r21915 event.current_buffer.reset()
Gil Forsyth
Have Ctrl-C in search mode clear query, if present...
r22241 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
Matthias Bussonnier
Do not redefine _, linter complain....
r22332 def _reset_search_buffer(event):
Gil Forsyth
Have Ctrl-C in search mode clear query, if present...
r22241 if event.current_buffer.document.text:
event.current_buffer.reset()
else:
event.cli.push_focus(DEFAULT_BUFFER)
Jonathan Slenders
ControlZ should suspend IPython to the background.
r22194 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
@kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
Matthias Bussonnier
Do not redefine _, linter complain....
r22332 def _suspend_to_bg(event):
Jonathan Slenders
ControlZ should suspend IPython to the background.
r22194 event.cli.suspend_to_background()
Thomas Kluyver
Tab key inserts four spaces at the start of the line...
r22136 @Condition
def cursor_in_leading_ws(cli):
before = cli.application.buffer.document.current_line_before_cursor
return (not before) or before.isspace()
# Ctrl+I == Tab
@kbmanager.registry.add_binding(Keys.ControlI,
filter=(HasFocus(DEFAULT_BUFFER)
& ~HasSelection()
& insert_mode
& cursor_in_leading_ws
))
Matthias Bussonnier
Do not redefine _, linter complain....
r22332 def _indent_buffer(event):
Thomas Kluyver
Tab key inserts four spaces at the start of the line...
r22136 event.current_buffer.insert_text(' ' * 4)
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 # Pre-populate history from IPython's history database
history = InMemoryHistory()
last_cell = u""
Matthias Bussonnier
Do not redefine _, linter complain....
r22332 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 include_latest=True):
# Ignore blank lines and consecutive duplicates
cell = cell.rstrip()
if cell and (cell != last_cell):
history.append(cell)
Thomas Kluyver
Refine multiline behaviour
r21912
Matthias Bussonnier
Make style and layout dynamic....
r22277 self._style = self._make_style_from_name(self.highlighting_style)
style = DynamicStyle(lambda: self._style)
Thomas Kluyver
Configure editing_mode instead of vi_mode...
r22301 editing_mode = getattr(EditingMode, self.editing_mode.upper())
Jonathan Slenders
Upgrade to prompt_toolkit 1.0.0.
r22296
Matthias Bussonnier
Make style and layout dynamic....
r22277 self._app = create_prompt_application(
Jonathan Slenders
Upgrade to prompt_toolkit 1.0.0.
r22296 editing_mode=editing_mode,
Matthias Bussonnier
Make style and layout dynamic....
r22277 key_bindings_registry=kbmanager.registry,
history=history,
completer=IPythonPTCompleter(self.Completer),
enable_history_search=True,
style=style,
mouse_support=self.mouse_support,
**self._layout_options()
)
self.pt_cli = CommandLineInterface(self._app,
eventloop=create_eventloop(self.inputhook))
def _make_style_from_name(self, name):
"""
Small wrapper that make an IPython compatible style from a style name
We need that to add style for prompt ... etc.
"""
style_cls = get_style_by_name(name)
Thomas Kluyver
Config options for syntax higlighting style
r21929 style_overrides = {
Thomas Kluyver
Nicer default colours
r21918 Token.Prompt: '#009900',
Token.PromptNum: '#00ff00 bold',
Thomas Kluyver
Config options for syntax higlighting style
r21929 }
Adrian
Do not use `is` for string comparison
r22320 if name == 'default':
Thomas Kluyver
Config options for syntax higlighting style
r21929 style_cls = get_style_by_name('default')
Thomas Kluyver
More tweaks to highlighting colours
r21939 # The default theme needs to be visible on both a dark background
# and a light background, because we can't tell what the terminal
# looks like. These tweaks to the default theme help with that.
Thomas Kluyver
Config options for syntax higlighting style
r21929 style_overrides.update({
Token.Number: '#007700',
Token.Operator: 'noinherit',
Token.String: '#BB6622',
Thomas Kluyver
More tweaks to highlighting colours
r21939 Token.Name.Function: '#2080D0',
Token.Name.Class: 'bold #2080D0',
Token.Name.Namespace: 'bold #2080D0',
Thomas Kluyver
Config options for syntax higlighting style
r21929 })
style_overrides.update(self.highlighting_style_overrides)
style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
style_dict=style_overrides)
Thomas Kluyver
Nicer default colours
r21918
Matthias Bussonnier
Make style and layout dynamic....
r22277 return style
def _layout_options(self):
"""
Return the current layout option for the current Terminal InteractiveShell
"""
return {
'lexer':IPythonPTLexer(),
'reserve_space_for_menu':self.space_for_menu,
'get_prompt_tokens':self.get_prompt_tokens,
'get_continuation_tokens':self.get_continuation_tokens,
Matthias Bussonnier
Re enable multi line in PT-TerminalInteractiveShell...
r22283 'multiline':True,
Jonathan Slenders
Added display_completions_in_columns option.
r22302 'display_completions_in_columns': self.display_completions_in_columns,
Matthias Bussonnier
Make style and layout dynamic....
r22277 }
Thomas Kluyver
Refine multiline behaviour
r21912
Matthias Bussonnier
Rename relayout to _update_layout
r22279 def _update_layout(self):
Matthias Bussonnier
Make style and layout dynamic....
r22277 """
Ask for a re computation of the application layout, if for example ,
some configuration options have changed.
"""
self._app.layout = create_prompt_layout(**self._layout_options())
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 def prompt_for_code(self):
Jonathan Slenders
Upgrade to prompt_toolkit 1.0.0.
r22296 document = self.pt_cli.run(
pre_run=self.pre_prompt, reset_current_buffer=True)
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 return document.text
Thomas Kluyver
Integrate colorama for coloured output on Windows
r21950 def init_io(self):
if sys.platform not in {'win32', 'cli'}:
return
import colorama
colorama.init()
# For some reason we make these wrappers around stdout/stderr.
# For now, we need to reset them so all output gets coloured.
# https://github.com/ipython/ipython/issues/8669
from IPython.utils import io
io.stdout = io.IOStream(sys.stdout)
io.stderr = io.IOStream(sys.stderr)
Thomas Kluyver
Restore terminal magics and aliases...
r22128 def init_magics(self):
super(TerminalInteractiveShell, self).init_magics()
self.register_magics(TerminalMagics)
def init_alias(self):
# The parent class defines aliases that can be safely used with any
# frontend.
super(TerminalInteractiveShell, self).init_alias()
# Now define aliases that only make sense on the terminal, because they
# need direct access to the console in a way that we can't emulate in
# GUI or web frontend
if os.name == 'posix':
for cmd in ['clear', 'more', 'less', 'man']:
self.alias_manager.soft_define_alias(cmd, cmd)
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 def __init__(self, *args, **kwargs):
Thomas Kluyver
Rename PTInteractiveShell to TerminalInteractiveShell...
r22112 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 self.init_prompt_toolkit_cli()
Min RK
support term_title in pt shell...
r22124 self.init_term_title()
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 self.keep_running = True
def ask_exit(self):
self.keep_running = False
Thomas Kluyver
Implement pre-filling prompt from set_next_input()
r21948 rl_next_input = None
def pre_prompt(self):
if self.rl_next_input:
Thomas Kluyver
Fix set_next_input on Python 2
r22011 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
Thomas Kluyver
Implement pre-filling prompt from set_next_input()
r21948 self.rl_next_input = None
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 def interact(self):
while self.keep_running:
Thomas Kluyver
Move printing blank line to before each input prompt
r21921 print(self.separate_in, end='')
Thomas Kluyver
Implement pre-filling prompt from set_next_input()
r21948
Thomas Kluyver
Do sensible things on Ctrl-C and Ctrl-D
r21915 try:
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 code = self.prompt_for_code()
Thomas Kluyver
Do sensible things on Ctrl-C and Ctrl-D
r21915 except EOFError:
Thomas Kluyver
Add and use confirm_exit flag in prompt_toolkit shell...
r22186 if (not self.confirm_exit) \
or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
Thomas Kluyver
Do sensible things on Ctrl-C and Ctrl-D
r21915 self.ask_exit()
else:
Thomas Kluyver
Fix 'interactive' tests using pipes to a subprocess
r22107 if code:
self.run_cell(code, store_history=True)
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
self.edit_syntax_error()
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Add a mainloop() method to mimic existing shell API
r22054 def mainloop(self):
# An extra layer of protection in case someone mashing Ctrl-C breaks
# out of our internal code.
while True:
try:
self.interact()
break
except KeyboardInterrupt:
print("\nKeyboardInterrupt escaped interact()\n")
Thomas Kluyver
Write & borrow some inputhooks for prompt_toolkit
r21934 _inputhook = None
def inputhook(self, context):
if self._inputhook is not None:
self._inputhook(context)
def enable_gui(self, gui=None):
if gui:
self._inputhook = get_inputhook_func(gui)
else:
self._inputhook = None
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 # Methods to support auto-editing of SyntaxErrors:
def edit_syntax_error(self):
"""The bottom half of the syntax error handler called in the main loop.
Loop until syntax error is fixed or user cancels.
"""
while self.SyntaxTB.last_syntax_error:
# copy and clear last_syntax_error
err = self.SyntaxTB.clear_err_state()
if not self._should_recompile(err):
return
try:
# may set last_syntax_error again if a SyntaxError is raised
self.safe_execfile(err.filename, self.user_ns)
except:
self.showtraceback()
else:
try:
Thomas Kluyver
Simplify code with a context manager
r22205 with open(err.filename) as f:
Thomas Kluyver
Restore option to auto-edit files on syntax error
r22204 # This should be inside a display_trap block and I
# think it is.
sys.displayhook(f.read())
except:
self.showtraceback()
def _should_recompile(self, e):
"""Utility routine for edit_syntax_error"""
if e.filename in ('<ipython console>', '<input>', '<string>',
'<console>', '<BackgroundJob compilation>',
None):
return False
try:
if (self.autoedit_syntax and
not self.ask_yes_no(
'Return to editor to correct syntax error? '
'[Y/n] ', 'y')):
return False
except EOFError:
return False
def int0(x):
try:
return int(x)
except TypeError:
return 0
# always pass integer line and offset values to editor hook
try:
self.hooks.fix_error_editor(e.filename,
int0(e.lineno), int0(e.offset),
e.msg)
except TryNext:
warn('Could not open editor')
return False
return True
Thomas Kluyver
Use system_raw in ptshell...
r22239 # Run !system commands directly, not through pipes, so terminal programs
# work correctly.
system = InteractiveShell.system_raw
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 if __name__ == '__main__':
Thomas Kluyver
Rename PTInteractiveShell to TerminalInteractiveShell...
r22112 TerminalInteractiveShell.instance().interact()