summaryrefslogtreecommitdiffstats
path: root/pgcli/pgstyle.py
diff options
context:
space:
mode:
authorIrina Truong <i.chernyavska@gmail.com>2018-09-28 14:18:40 -0700
committerGitHub <noreply@github.com>2018-09-28 14:18:40 -0700
commit392491a74d2d8abcb2c0db5230fc7f11502c6ba9 (patch)
tree20f88af6503783b0bc9880a440f5674264fa4220 /pgcli/pgstyle.py
parentd3bdb891d309622cbf4e59244a698def8a8bbd2d (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.py114
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