From 391f414782898f9360eb07c0213d032710f4bf28 Mon Sep 17 00:00:00 2001 From: Jonathan Slenders Date: Sat, 10 Feb 2018 17:20:53 +0100 Subject: [PATCH] Prompt_toolkit 2.0 compatibility. --- xonsh/ptk/completer.py | 5 ++++- xonsh/ptk/key_bindings.py | 35 +++++++++++++++++++++++++++-------- xonsh/ptk/shell.py | 9 ++++++--- xonsh/ptk/shortcuts.py | 9 ++++++++- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/xonsh/ptk/completer.py b/xonsh/ptk/completer.py index 704f6ed9d..0f1d29da9 100644 --- a/xonsh/ptk/completer.py +++ b/xonsh/ptk/completer.py @@ -93,7 +93,10 @@ class PromptToolkitCompleter(Completer): def reserve_space(self): cli = builtins.__xonsh_shell__.shell.prompter.cli - window = cli.application.layout.children[0].content.children[1] + try: + window = cli.application.layout.children[0].content.children[1] + except AttributeError: # PTK 2.0 + window = cli.app.layout.container.children[0].content.children[1].content if window and window.render_info: h = window.render_info.content_height diff --git a/xonsh/ptk/key_bindings.py b/xonsh/ptk/key_bindings.py index 9a5cef2a9..b597ce0b8 100644 --- a/xonsh/ptk/key_bindings.py +++ b/xonsh/ptk/key_bindings.py @@ -61,7 +61,10 @@ def carriage_return(b, cli, *, autoindent=True): elif current_line_blank and in_partial_string: b.newline(copy_margin=autoindent) else: - b.accept_action.validate_and_handle(cli, b) + try: + b.accept_action.validate_and_handle(cli, b) + except AttributeError: # PTK 2.0 + b.validate_and_handle() def _is_blank(l): @@ -138,8 +141,12 @@ def ctrl_d_condition(): raise EOFError else: app = get_app() - return (app.current_buffer_name == DEFAULT_BUFFER and - not app.current_buffer.text) + try: + buffer_name = app.current_buffer_name + except AttributeError: # PTK 2.0 + buffer_name = app.current_buffer.name + + return buffer_name == DEFAULT_BUFFER and not app.current_buffer.text @Condition @@ -282,16 +289,21 @@ def load_xonsh_bindings(key_bindings): def call_exit_alias(event): """Use xonsh exit function""" b = event.cli.current_buffer - b.accept_action.validate_and_handle(event.cli, b) + try: + b.accept_action.validate_and_handle(event.cli, b) + except AttributeError: # PTK 2.0 + b.validate_and_handle() xonsh_exit([]) @handle(Keys.ControlJ, filter=IsMultiline()) + @handle(Keys.ControlM, filter=IsMultiline()) def multiline_carriage_return(event): """ Wrapper around carriage_return multiline parser """ b = event.cli.current_buffer carriage_return(b, event.cli) @handle(Keys.ControlJ, filter=should_confirm_completion) + @handle(Keys.ControlM, filter=should_confirm_completion) def enter_confirm_completion(event): """Ignore (confirm completion)""" event.current_buffer.complete_state = None @@ -305,7 +317,10 @@ def load_xonsh_bindings(key_bindings): def execute_block_now(event): """Execute a block of text irrespective of cursor position""" b = event.cli.current_buffer - b.accept_action.validate_and_handle(event.cli, b) + try: + b.accept_action.validate_and_handle(event.cli, b) + except AttributeError: # PTK 2.0 + b.validate_and_handle() @handle(Keys.Left, filter=beginning_of_line) def wrap_cursor_back(event): @@ -338,16 +353,20 @@ def load_xonsh_bindings(key_bindings): """ b = event.current_buffer + try: + start_completion = event.cli.start_completion + except AttributeError: # PTK 2.0 + start_completion = event.current_buffer.start_completion + def second_tab(): if b.complete_state: b.complete_next() else: - event.cli.start_completion(select_first=False) + start_completion(select_first=False) # On the second tab-press, or when already navigating through # completions. if event.is_repeat or b.complete_state: second_tab() else: - event.cli.start_completion(insert_common_part=True, - select_first=False) + start_completion(insert_common_part=True, select_first=False) diff --git a/xonsh/ptk/shell.py b/xonsh/ptk/shell.py index 3d58987d9..2f41a9d13 100644 --- a/xonsh/ptk/shell.py +++ b/xonsh/ptk/shell.py @@ -4,7 +4,10 @@ import sys import builtins from prompt_toolkit.auto_suggest import AutoSuggestFromHistory -from prompt_toolkit.layout.lexers import PygmentsLexer +try: + from prompt_toolkit.layout.lexers import PygmentsLexer +except ImportError: + from prompt_toolkit.lexers import PygmentsLexer from xonsh.platform import ptk_version_info from xonsh.base_shell import BaseShell @@ -30,8 +33,8 @@ else: # ptk 2.0 from prompt_toolkit.shortcuts import print_formatted_text as ptk_print from prompt_toolkit.shortcuts import CompleteStyle from prompt_toolkit.formatted_text import PygmentsTokens - from prompt_toolkit.styles.pygments import ( - style_from_pygments, Style, pygments_token_to_classname) + from prompt_toolkit.styles.pygments import Style, pygments_token_to_classname + from prompt_toolkit.styles.pygments import style_from_pygments_cls as style_from_pygments Token = _TokenType() diff --git a/xonsh/ptk/shortcuts.py b/xonsh/ptk/shortcuts.py index 8a717fa87..d47968c9b 100644 --- a/xonsh/ptk/shortcuts.py +++ b/xonsh/ptk/shortcuts.py @@ -162,7 +162,14 @@ class Prompter2(object): editing_mode = EditingMode.EMACS kwargs['editing_mode'] = editing_mode - self.cli.prompt(message=message, **kwargs) + + # A bottom toolbar is displayed if some FormattedText has been passed. + # However, if this is an empty list, we don't want to show a toolbar. + # (Better would be to pass `None`.) + if kwargs['bottom_toolbar'] and kwargs['bottom_toolbar'].__pt_formatted_text__() == []: + kwargs['bottom_toolbar'] = None + + return self.cli.prompt(message=message, **kwargs) def reset(self): """Resets the prompt and cli to a pristine state on this object."""