##// END OF EJS Templates
Add continuation prompts
Add continuation prompts

File last commit:

r21933:995b7940
r21933:995b7940
Show More
ptshell.py
163 lines | 5.9 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
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from IPython.core.interactiveshell import InteractiveShell
Thomas Kluyver
Python 2.7 support & highlighting in prompt_toolkit interface
r21930 from IPython.utils.py3compat import PY3
Thomas Kluyver
Config options for syntax higlighting style
r21929 from traitlets import Bool, Unicode, Dict
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
Thomas Kluyver
Only use our Enter handling when the default buffer is active...
r21923 from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.filters import HasFocus, HasSelection
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 from prompt_toolkit.history import InMemoryHistory
Thomas Kluyver
Refine multiline behaviour
r21912 from prompt_toolkit.shortcuts import create_prompt_application
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
Thomas Kluyver
Add config option for vi mode
r21928 from prompt_toolkit.key_binding.vi_state import InputMode
from prompt_toolkit.key_binding.bindings.vi import ViStateFilter
Thomas Kluyver
Refine multiline behaviour
r21912 from prompt_toolkit.keys import Keys
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from prompt_toolkit.layout.lexers import PygmentsLexer
Thomas Kluyver
Nicer default colours
r21918 from prompt_toolkit.styles import PygmentsStyle
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
Thomas Kluyver
Config options for syntax higlighting style
r21929 from pygments.styles import get_style_by_name
Thomas Kluyver
Python 2.7 support & highlighting in prompt_toolkit interface
r21930 from pygments.lexers import Python3Lexer, PythonLexer
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 from pygments.token import Token
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:
yield Completion(m, start_position=start_pos)
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 class PTInteractiveShell(InteractiveShell):
Thomas Kluyver
Turn out prompt & traceback colours on when using prompt_toolkit
r21920 colors_force = True
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 pt_cli = None
Thomas Kluyver
Add config option for vi mode
r21928 vi_mode = Bool(False, config=True,
help="Use vi style keybindings at the prompt",
)
Thomas Kluyver
Config options for syntax higlighting style
r21929 highlighting_style = Unicode('', config=True,
help="The name of a Pygments style to use for syntax highlighting"
)
highlighting_style_overrides = Dict(config=True,
help="Override highlighting format for specific tokens"
)
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 [
(Token.Prompt, (' ' * (width - 2)) + ': '),
]
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
def init_prompt_toolkit_cli(self):
Thomas Kluyver
Add config option for vi mode
r21928 kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode)
insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT)
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
if not b.document.on_last_line:
b.newline()
return
status, indent = self.input_splitter.check_complete(b.document.text)
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
Do sensible things on Ctrl-C and Ctrl-D
r21915 @kbmanager.registry.add_binding(Keys.ControlC)
def _(event):
event.current_buffer.reset()
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""
for _, _, cell in self.history_manager.get_tail(self.history_load_length,
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
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 }
if self.highlighting_style:
style_cls = get_style_by_name(self.highlighting_style)
else:
style_cls = get_style_by_name('default')
style_overrides.update({
Token.Number: '#007700',
Token.Operator: 'noinherit',
Token.String: '#BB6622',
})
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
Thomas Kluyver
Refine multiline behaviour
r21912 app = create_prompt_application(multiline=True,
Thomas Kluyver
Python 2.7 support & highlighting in prompt_toolkit interface
r21930 lexer=PygmentsLexer(Python3Lexer if PY3 else PythonLexer),
Thomas Kluyver
Refine multiline behaviour
r21912 get_prompt_tokens=self.get_prompt_tokens,
Thomas Kluyver
Add continuation prompts
r21933 get_continuation_tokens=self.get_continuation_tokens,
Thomas Kluyver
Refine multiline behaviour
r21912 key_bindings_registry=kbmanager.registry,
Thomas Kluyver
Hook up command history and populate it from IPython's history DB
r21914 history=history,
Thomas Kluyver
Add completion support
r21916 completer=IPythonPTCompleter(self.Completer),
Thomas Kluyver
Enable history search with up arrow
r21924 enable_history_search=True,
Thomas Kluyver
Nicer default colours
r21918 style=style,
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 )
Thomas Kluyver
Refine multiline behaviour
r21912
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911 self.pt_cli = CommandLineInterface(app)
def __init__(self, *args, **kwargs):
super(PTInteractiveShell, self).__init__(*args, **kwargs)
self.init_prompt_toolkit_cli()
self.keep_running = True
def ask_exit(self):
self.keep_running = False
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
Do sensible things on Ctrl-C and Ctrl-D
r21915 try:
document = self.pt_cli.run()
except EOFError:
if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
self.ask_exit()
else:
if document:
self.run_cell(document.text, store_history=True)
Thomas Kluyver
Initial code for new InteractiveShell subclass using prompt_toolkit
r21911
if __name__ == '__main__':
Thomas Kluyver
Add completion support
r21916 PTInteractiveShell.instance().interact()