diff options
author | Irina Truong <i.chernyavska@gmail.com> | 2018-09-28 14:18:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-28 14:18:40 -0700 |
commit | 392491a74d2d8abcb2c0db5230fc7f11502c6ba9 (patch) | |
tree | 20f88af6503783b0bc9880a440f5674264fa4220 /pgcli/pgstyle.py | |
parent | d3bdb891d309622cbf4e59244a698def8a8bbd2d (diff) |
Cherry-picked prompt-toolkit 2.0 changes. (#930)
* Cherry-picked prompt-toolkit 2.0 changes.
* Increase help timeout.
* Missed one.
* Fixes editor command.
* Expect exact to fix named query error.
* Unicode is non-optional with ptk 2.0.
* Unicode literals all the things (almost).
* PEP8.
* Change how we swap completers.
* By default, bottom toolbar styles are reversed. We don't want that.
* Adapt styles to 2.0.
* The future is now. Switch to ptk 2.0 style names.
* PEP8.
* Flag for enable_open_in_editor.
* add class:prompt to prompt
* Removed workaround for #668. Some renaming.
* use pgcli.completer instead of app.current_buffer.completer
* enable_system_prompt=True like old prompt toolkit
* keep search_ignore_case enabled (was ignore_case)
* fix closing parenthese
* keep marking class:continuation token for continuation
* capture KeyboardInterrupt manually
AbortAction has been removed in Prompt_toolkit 2.0
* replace C-J with enter, add more comments
* reversed ([...]) to [(...)] (oops)
* pep8 fixes
* Does Vi mode have to be applied to session every time?
* (workaround) also enable vi_mode after edit command
* Fixed test errors after rebasing on master.
Diffstat (limited to 'pgcli/pgstyle.py')
-rw-r--r-- | pgcli/pgstyle.py | 114 |
1 files changed, 94 insertions, 20 deletions
diff --git a/pgcli/pgstyle.py b/pgcli/pgstyle.py index 54ae1bbe..bde464c1 100644 --- a/pgcli/pgstyle.py +++ b/pgcli/pgstyle.py @@ -1,9 +1,64 @@ -from pygments.token import string_to_tokentype -from pygments.util import ClassNotFound -from prompt_toolkit.styles import PygmentsStyle +from __future__ import unicode_literals + +import logging + import pygments.styles +from pygments.token import string_to_tokentype, Token +from pygments.style import Style as PygmentsStyle +from pygments.util import ClassNotFound +from prompt_toolkit.styles.pygments import style_from_pygments_cls +from prompt_toolkit.styles import merge_styles, Style + +logger = logging.getLogger(__name__) + +# map Pygments tokens (ptk 1.0) to class names (ptk 2.0). +TOKEN_TO_PROMPT_STYLE = { + Token.Menu.Completions.Completion.Current: 'completion-menu.completion.current', + Token.Menu.Completions.Completion: 'completion-menu.completion', + Token.Menu.Completions.Meta.Current: 'completion-menu.meta.completion.current', + Token.Menu.Completions.Meta: 'completion-menu.meta.completion', + Token.Menu.Completions.MultiColumnMeta: 'completion-menu.multi-column-meta', + Token.Menu.Completions.ProgressButton: 'scrollbar.arrow', # best guess + Token.Menu.Completions.ProgressBar: 'scrollbar', # best guess + Token.SelectedText: 'selected', + Token.SearchMatch: 'search', + Token.SearchMatch.Current: 'search.current', + Token.Toolbar: 'bottom-toolbar', + Token.Toolbar.Off: 'bottom-toolbar.off', + Token.Toolbar.On: 'bottom-toolbar.on', + Token.Toolbar.Search: 'search-toolbar', + Token.Toolbar.Search.Text: 'search-toolbar.text', + Token.Toolbar.System: 'system-toolbar', + Token.Toolbar.Arg: 'arg-toolbar', + Token.Toolbar.Arg.Text: 'arg-toolbar.text', + Token.Toolbar.Transaction.Valid: 'bottom-toolbar.transaction.valid', + Token.Toolbar.Transaction.Failed: 'bottom-toolbar.transaction.failed', + Token.Output.Header: 'output.header', + Token.Output.OddRow: 'output.odd-row', + Token.Output.EvenRow: 'output.even-row', +} + +# reverse dict for cli_helpers, because they still expect Pygments tokens. +PROMPT_STYLE_TO_TOKEN = { + v: k for k, v in TOKEN_TO_PROMPT_STYLE.items() +} + + +def parse_pygments_style(token_name, style_object, style_dict): + """Parse token type and style string. + + :param token_name: str name of Pygments token. Example: "Token.String" + :param style_object: pygments.style.Style instance to use as base + :param style_dict: dict of token names and their styles, customized to this cli + + """ + token_type = string_to_tokentype(token_name) + try: + other_token_type = string_to_tokentype(style_dict[token_name]) + return token_type, style_object.styles[other_token_type] + except AttributeError as err: + return token_type, style_dict[token_name] -from pygments.style import Style def style_factory(name, cli_style): try: @@ -11,16 +66,31 @@ def style_factory(name, cli_style): except ClassNotFound: style = pygments.styles.get_style_by_name('native') - custom_styles = {} + prompt_styles = [] + # prompt-toolkit used pygments tokens for styling before, switched to style + # names in 2.0. Convert old token types to new style names, for backwards compatibility. for token in cli_style: - try: - custom_styles[string_to_tokentype( - token)] = style.styles[string_to_tokentype(cli_style[token])] - except AttributeError as err: - custom_styles[string_to_tokentype(token)] = cli_style[token] + if token.startswith('Token.'): + # treat as pygments token (1.0) + token_type, style_value = parse_pygments_style( + token, style, cli_style) + if token_type in TOKEN_TO_PROMPT_STYLE: + prompt_style = TOKEN_TO_PROMPT_STYLE[token_type] + prompt_styles.append((prompt_style, style_value)) + else: + # we don't want to support tokens anymore + logger.error('Unhandled style / class name: %s', token) + else: + # treat as prompt style name (2.0). See default style names here: + # https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/styles/defaults.py + prompt_styles.append((token, cli_style[token])) - return PygmentsStyle.from_defaults(style_dict=custom_styles, - pygments_style_cls=style) + override_style = Style([('bottom-toolbar', 'noreverse')]) + return merge_styles([ + style_from_pygments_cls(style), + override_style, + Style(prompt_styles) + ]) def style_factory_output(name, cli_style): @@ -30,14 +100,18 @@ def style_factory_output(name, cli_style): style = pygments.styles.get_style_by_name('native').styles for token in cli_style: - try: - style.update({string_to_tokentype( - token): style[string_to_tokentype(cli_style[token])], }) - except AttributeError as err: - style.update( - {string_to_tokentype(token): cli_style[token], }) - - class OutputStyle(pygments.style.Style): + if token.startswith('Token.'): + token_type, style_value = parse_pygments_style( + token, style, cli_style) + style.update({token_type: style_value}) + elif token in PROMPT_STYLE_TO_TOKEN: + token_type = PROMPT_STYLE_TO_TOKEN[token] + style.update({token_type: cli_style[token]}) + else: + # TODO: cli helpers will have to switch to ptk.Style + logger.error('Unhandled style / class name: %s', token) + + class OutputStyle(PygmentsStyle): default_style = "" styles = style |