From ecdc51a4be9100f63dee156a0fac273c6c7f647c 2016-06-01 11:13:13 From: Thomas Kluyver Date: 2016-06-01 11:13:13 Subject: [PATCH] New prompts class for terminal interface --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index c446281..908f81c 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2339,16 +2339,9 @@ class InteractiveShell(SingletonConfigurable): """ if not self.show_rewritten_input: return - - rw = self.prompt_manager.render('rewrite') + cmd - try: - # plain ascii works better w/ pyreadline, on some machines, so - # we use it and only print uncolored rewrite if we have unicode - rw = str(rw) - print(rw) - except UnicodeEncodeError: - print("------> " + cmd) + # This is overridden in TerminalInteractiveShell to use fancy prompts + print("------> " + cmd) #------------------------------------------------------------------------- # Things related to extracting values/expressions from kernel and user_ns diff --git a/IPython/terminal/prompts.py b/IPython/terminal/prompts.py new file mode 100644 index 0000000..f39707b --- /dev/null +++ b/IPython/terminal/prompts.py @@ -0,0 +1,36 @@ +from pygments.token import Token + +class Prompts(object): + def __init__(self, shell): + self.shell = shell + + def in_prompt_tokens(self, cli=None): + return [ + (Token.Prompt, 'In ['), + (Token.PromptNum, str(self.shell.execution_count)), + (Token.Prompt, ']: '), + ] + + def _width(self): + in_tokens = self.in_prompt_tokens() + return sum(len(s) for (t, s) in in_tokens) + + def continuation_prompt_tokens(self, cli=None, width=None): + if width is None: + width = self._width() + return [ + (Token.Prompt, (' ' * (width - 5)) + '...: '), + ] + + def rewrite_prompt_tokens(self): + width = self._width() + return [ + (Token.Prompt, ('-' * (width - 2)) + '> '), + ] + + def out_prompt_tokens(self): + return [ + (Token.OutPrompt, 'Out['), + (Token.OutPromptNum, str(self.shell.execution_count)), + (Token.OutPrompt, ']: '), + ] diff --git a/IPython/terminal/ptshell.py b/IPython/terminal/ptshell.py index cb63634..fcc64e8 100644 --- a/IPython/terminal/ptshell.py +++ b/IPython/terminal/ptshell.py @@ -11,7 +11,7 @@ from IPython.core.interactiveshell import InteractiveShell from IPython.utils.py3compat import cast_unicode_py2, input from IPython.utils.terminal import toggle_set_term_title, set_term_title from IPython.utils.process import abbrev_cwd -from traitlets import Bool, Unicode, Dict, Integer, observe +from traitlets import Bool, Unicode, Dict, Integer, observe, Instance from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode from prompt_toolkit.filters import HasFocus, HasSelection, Condition, ViInsertMode, EmacsInsertMode, IsDone @@ -29,6 +29,7 @@ from pygments.token import Token from .debugger import TerminalPdb, Pdb from .pt_inputhooks import get_inputhook_func from .interactiveshell import get_default_editor, TerminalMagics +from .prompts import Prompts from .ptutils import IPythonPTCompleter, IPythonPTLexer _use_simple_prompt = 'IPY_TEST_SIMPLE_PROMPT' in os.environ or not sys.stdin.isatty() @@ -98,6 +99,11 @@ class TerminalInteractiveShell(InteractiveShell): editor = Unicode(get_default_editor(), help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." ).tag(config=True) + + prompts = Instance(Prompts) + + def _prompts_default(self): + return Prompts(self) term_title = Bool(True, help="Automatically set the terminal title" @@ -120,18 +126,6 @@ class TerminalInteractiveShell(InteractiveShell): else: toggle_set_term_title(False) - def get_prompt_tokens(self, cli): - return [ - (Token.Prompt, 'In ['), - (Token.PromptNum, str(self.execution_count)), - (Token.Prompt, ']: '), - ] - - def get_continuation_tokens(self, cli, width): - return [ - (Token.Prompt, (' ' * (width - 5)) + '...: '), - ] - def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. @@ -261,8 +255,8 @@ class TerminalInteractiveShell(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, + 'get_prompt_tokens':self.prompts.in_prompt_tokens, + 'get_continuation_tokens':self.prompts.continuation_prompt_tokens, 'multiline':True, 'display_completions_in_columns': self.display_completions_in_columns, @@ -439,6 +433,19 @@ class TerminalInteractiveShell(InteractiveShell): # work correctly. system = InteractiveShell.system_raw + def auto_rewrite_input(self, cmd): + """Overridden from the parent class to use fancy rewriting prompt""" + if not self.show_rewritten_input: + return + + tokens = self.prompts.rewrite_prompt_tokens() + if self.pt_cli: + self.pt_cli.print_tokens(tokens) + print(cmd) + else: + prompt = ''.join(s for t, s in tokens) + print(prompt, cmd, sep='') + if __name__ == '__main__': TerminalInteractiveShell.instance().interact()