From 3392b27919b06be23fbd9cd1b4338eeaf0d48312 Mon Sep 17 00:00:00 2001 From: Jonathan Slenders Date: Sat, 30 Dec 2017 19:51:14 +0100 Subject: [PATCH] Upgrade to prompt_toolkit 2.0 --- haxor_news/haxor.py | 76 +++++++++++++++++++------------------------ haxor_news/keys.py | 28 +++++++--------- haxor_news/main.py | 7 ++-- haxor_news/style.py | 51 ++++++++++++++--------------- haxor_news/toolbar.py | 7 ++-- setup.py | 2 +- 6 files changed, 76 insertions(+), 95 deletions(-) diff --git a/haxor_news/haxor.py b/haxor_news/haxor.py index 6796cd0..252640f 100644 --- a/haxor_news/haxor.py +++ b/haxor_news/haxor.py @@ -21,13 +21,11 @@ import sys import click -from prompt_toolkit import AbortAction, Application, CommandLineInterface -from prompt_toolkit.filters import Always -from prompt_toolkit.interface import AcceptAction +from prompt_toolkit import Application from prompt_toolkit.buffer import Buffer -from prompt_toolkit.shortcuts import create_default_layout, create_eventloop from prompt_toolkit.history import FileHistory from prompt_toolkit.auto_suggest import AutoSuggestFromHistory +from prompt_toolkit.shortcuts.prompt import PromptSession from .__init__ import __version__ from .completer import Completer @@ -41,8 +39,8 @@ class Haxor(object): """Encapsulate the Hacker News CLI. - :type cli: :class:`prompt_toolkit.CommandLineInterface` - :param cli: An instance of `prompt_toolkit.CommandLineInterface`. + :type prompt: :class:`prompt_toolkit.shortcuts.prompt.PromptSession` + :param prompt: An instance of `prompt_toolkit.shortcuts.prompt.PromptSession`. :type CMDS_ENABLE_PAGINATE: list (const) :param CMDS_ENABLE_PAGINATE: A list of commands that kick off pagination. @@ -99,7 +97,7 @@ class Haxor(object): PAGINATE_CMD_WIN = ' | more' def __init__(self): - self.cli = None + self.prompt = None self.key_manager = None self.theme = 'vim' self.paginate_comments = True @@ -137,33 +135,24 @@ def _create_cli(self): """Create the prompt_toolkit's CommandLineInterface.""" history = FileHistory(os.path.expanduser('~/.haxornewshistory')) toolbar = Toolbar(lambda: self.paginate_comments) - layout = create_default_layout( + self.key_manager = self._create_key_manager() + style_factory = StyleFactory(self.theme) + self.prompt = PromptSession( message=u'haxor> ', reserve_space_for_menu=8, - get_bottom_toolbar_tokens=toolbar.handler, - ) - cli_buffer = Buffer( + bottom_toolbar=toolbar.handler, + mouse_support=False, + style=style_factory.style, history=history, auto_suggest=AutoSuggestFromHistory(), enable_history_search=True, completer=self.completer, - complete_while_typing=Always(), - accept_action=AcceptAction.RETURN_DOCUMENT) - self.key_manager = self._create_key_manager() - style_factory = StyleFactory(self.theme) - application = Application( - mouse_support=False, - style=style_factory.style, - layout=layout, - buffer=cli_buffer, - key_bindings_registry=self.key_manager.manager.registry, - on_exit=AbortAction.RAISE_EXCEPTION, - on_abort=AbortAction.RETRY, - ignore_case=True) - eventloop = create_eventloop() - self.cli = CommandLineInterface( - application=application, - eventloop=eventloop) + complete_while_typing=True, + + enable_open_in_editor=True, + enable_system_prompt=True, + enable_suspend=True, + key_bindings=self.key_manager.key_bindings) def _add_comment_pagination(self, document_text): """Add the command to enable comment pagination where applicable. @@ -185,24 +174,19 @@ def _add_comment_pagination(self, document_text): document_text += self.PAGINATE_CMD return document_text - def handle_exit(self, document): - """Exits if the user typed exit or quit - - :type document: :class:`prompt_toolkit.document.Document` - :param document: An instance of `prompt_toolkit.document.Document`. + def handle_exit(self, text): """ - if document.text in ('exit', 'quit'): + Exits if the user typed exit or quit + """ + if text in ('exit', 'quit'): sys.exit() - def run_command(self, document): - """Run the given command. - - :type document: :class:`prompt_toolkit.document.Document` - :param document: An instance of `prompt_toolkit.document.Document`. + def run_command(self, text): + """ + Run the given command. """ try: if self.paginate_comments: - text = document.text text = self._add_comment_pagination(text) subprocess.call(text, shell=True) except Exception as e: @@ -213,6 +197,12 @@ def run_cli(self): click.echo('Version: ' + __version__) click.echo('Syntax: hn [params] [options]') while True: - document = self.cli.run(reset_current_buffer=True) - self.handle_exit(document) - self.run_command(document) + try: + text = self.prompt.prompt() + except KeyboardInterrupt: + continue # Control-C was pressed. + except EOFError: + break + + self.handle_exit(text) + self.run_command(text) diff --git a/haxor_news/keys.py b/haxor_news/keys.py index efdeeb1..5e2cd53 100644 --- a/haxor_news/keys.py +++ b/haxor_news/keys.py @@ -14,7 +14,7 @@ # language governing permissions and limitations under the License. from __future__ import print_function -from prompt_toolkit.key_binding.manager import KeyBindingManager +from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.keys import Keys @@ -24,14 +24,12 @@ class KeyManager(object): Handle togging of: * Comment pagination. - :type manager: :class:`prompt_toolkit.key_binding.manager. - KeyBindingManager` - :param manager: An instance of `prompt_toolkit.key_binding.manager. - KeyBindingManager`. + :type key_bindings: :class:`prompt_toolkit.key_binding.KeyBindings` + :param key_bindings: An instance of `prompt_toolkit.key_binding.KeyBindings` """ def __init__(self, set_paginate_comments, get_paginate_comments): - self.manager = None + self.key_bindings = None self._create_key_manager(set_paginate_comments, get_paginate_comments) def _create_key_manager(self, set_paginate_comments, get_paginate_comments): @@ -50,13 +48,9 @@ def _create_key_manager(self, set_paginate_comments, get_paginate_comments): """ assert callable(set_paginate_comments) assert callable(get_paginate_comments) - self.manager = KeyBindingManager( - enable_search=True, - enable_abort_and_exit_bindings=True, - enable_system_bindings=True, - enable_auto_suggest_bindings=True) + self.key_bindings = KeyBindings() - @self.manager.registry.add_binding(Keys.F2) + @self.key_bindings.add('f2') def handle_f2(_): """Enable/Disable paginate comments mode. @@ -70,8 +64,8 @@ def handle_f2(_): # set_paginate_comments(not get_paginate_comments()) pass - @self.manager.registry.add_binding(Keys.F10) - def handle_f10(_): + @self.key_bindings.add('f10') + def handle_f10(event): """Quit when the `F10` key is pressed. :type _: :class:`prompt_toolkit.Event` @@ -79,9 +73,9 @@ def handle_f10(_): :raises: :class:`EOFError` to quit the app. """ - raise EOFError + event.app.exit() - @self.manager.registry.add_binding(Keys.ControlSpace) + @self.key_bindings.add('c-space') def handle_ctrl_space(event): """Initialize autocompletion at the cursor. @@ -97,4 +91,4 @@ def handle_ctrl_space(event): if b.complete_state: b.complete_next() else: - event.cli.start_completion(select_first=False) + b.start_completion(select_first=False) diff --git a/haxor_news/main.py b/haxor_news/main.py index e2d1837..69d8fb0 100644 --- a/haxor_news/main.py +++ b/haxor_news/main.py @@ -21,11 +21,8 @@ def cli(): """Creates and calls Haxor.""" - try: - haxor = Haxor() - haxor.run_cli() - except (EOFError, KeyboardInterrupt): - haxor.cli.set_return_value(None) + haxor = Haxor() + haxor.run_cli() if __name__ == "__main__": diff --git a/haxor_news/style.py b/haxor_news/style.py index 1ebb980..49a7d46 100644 --- a/haxor_news/style.py +++ b/haxor_news/style.py @@ -15,7 +15,8 @@ from pygments.token import Token from pygments.util import ClassNotFound -from prompt_toolkit.styles import default_style_extensions, style_from_dict +from prompt_toolkit.styles.pygments import style_from_pygments_dict, style_from_pygments_cls +from prompt_toolkit.styles import merge_styles import pygments.styles @@ -41,31 +42,29 @@ def style_factory(self, name): :return: An instance of `pygments.style.StyleMeta`. """ try: - style = pygments.styles.get_style_by_name(name) + pygments_style = pygments.styles.get_style_by_name(name) except ClassNotFound: - style = pygments.styles.get_style_by_name('native') + pygments_style = pygments.styles.get_style_by_name('native') # Create styles dictionary. - styles = {} - styles.update(style.styles) - styles.update(default_style_extensions) - styles.update({ - Token.Menu.Completions.Completion.Current: 'bg:#00aaaa #000000', - Token.Menu.Completions.Completion: 'bg:#008888 #ffffff', - Token.Menu.Completions.Meta.Current: 'bg:#00aaaa #000000', - Token.Menu.Completions.Meta: 'bg:#00aaaa #ffffff', - Token.Menu.Completions.ProgressButton: 'bg:#003333', - Token.Menu.Completions.ProgressBar: 'bg:#00aaaa', - Token.Scrollbar: 'bg:#00aaaa', - Token.Scrollbar.Button: 'bg:#003333', - Token.Toolbar: 'bg:#222222 #cccccc', - Token.Toolbar.Off: 'bg:#222222 #696969', - Token.Toolbar.On: 'bg:#222222 #ffffff', - Token.Toolbar.Search: 'noinherit bold', - Token.Toolbar.Search.Text: 'nobold', - Token.Toolbar.System: 'noinherit bold', - Token.Toolbar.Arg: 'noinherit bold', - Token.Toolbar.Arg.Text: 'nobold' - }) - - return style_from_dict(styles) + return merge_styles([ + style_from_pygments_cls(pygments_style), + style_from_pygments_dict({ + Token.Menu.Completions.Completion.Current: 'bg:#00aaaa #000000', + Token.Menu.Completions.Completion: 'bg:#008888 #ffffff', + Token.Menu.Completions.Meta.Current: 'bg:#00aaaa #000000', + Token.Menu.Completions.Meta: 'bg:#00aaaa #ffffff', + Token.Menu.Completions.ProgressButton: 'bg:#003333', + Token.Menu.Completions.ProgressBar: 'bg:#00aaaa', + Token.Scrollbar: 'bg:#00aaaa', + Token.Scrollbar.Button: 'bg:#003333', + Token.Toolbar: 'bg:#222222 #cccccc', + Token.Toolbar.Off: 'bg:#222222 #696969', + Token.Toolbar.On: 'bg:#222222 #ffffff', + Token.Toolbar.Search: 'noinherit bold', + Token.Toolbar.Search.Text: 'nobold', + Token.Toolbar.System: 'noinherit bold', + Token.Toolbar.Arg: 'noinherit bold', + Token.Toolbar.Arg.Text: 'nobold' + }) + ]) diff --git a/haxor_news/toolbar.py b/haxor_news/toolbar.py index 4813ea9..fb806f5 100644 --- a/haxor_news/toolbar.py +++ b/haxor_news/toolbar.py @@ -15,6 +15,7 @@ from __future__ import print_function from pygments.token import Token +from prompt_toolkit.formatted_text import PygmentsTokens class Toolbar(object): @@ -38,7 +39,7 @@ def _create_toolbar_handler(self, paginate_comments_cfg): """ assert callable(paginate_comments_cfg) - def get_toolbar_items(_): + def get_toolbar_items(): """Return the toolbar items. :type _: :class:`prompt_toolkit.Cli` @@ -53,10 +54,10 @@ def get_toolbar_items(_): # else: # paginate_comments_token = Token.Toolbar.Off # paginate_comments = 'OFF' - return [ + return PygmentsTokens([ # (paginate_comments_token, # ' [F2] Paginate Comments: {0} '.format(paginate_comments)), (Token.Toolbar, ' [F10] Exit ') - ] + ]) return get_toolbar_items diff --git a/setup.py b/setup.py index da5d73a..b003a9b 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ 'colorama>=0.3.3,<1.0.0', 'requests>=2.4.3,<3.0.0', 'pygments>=2.0.2,<3.0.0', - 'prompt-toolkit>=1.0.0,<1.1.0', + 'prompt-toolkit>=2.0.0,<2.1.0', 'six>=1.9.0,<2.0.0', ], extras_require={