From ff6ae82ad9177b61310de575ea2b0a4885e8c480 Mon Sep 17 00:00:00 2001 From: Roland Walker Date: Sat, 28 Feb 2026 13:48:52 -0500 Subject: [PATCH] handle/document more attributes such as "dim" Handle and document more attributes for the [colors] section of the ~/.myclirc configuration file. This is a bit tricky as we try to support both Pygments and prompt_toolkit attribute names, and there is some mismatch between them. Before adding any style item we check it in a "try" block to see if it is supported (for the software, not the terminal). This works fine, with the only downside being that we silently swallow some spelling errors, applying no style in that case. We cannot reasonably warn in all such cases, since there exist styles supported by one library and not the other. In the end, we gain the support of new attributes such as "dim" and "strike". Some, such as "hidden", may not be supported most terminals. Other attributes exist, such as "roman", but it isn't clear that they are supported anywhere, so they are not documented. --- changelog.md | 1 + mycli/clistyle.py | 37 ++++++++++++++++++++++++++++++++----- mycli/myclirc | 5 ++++- test/myclirc | 5 ++++- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 5b1d5f98..1feffd1a 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,7 @@ Features * Set up customization of prompt/continuation colors in `~/.myclirc`. * Allow customization of the toolbar with prompt format strings. * Add warnings-count prompt format strings: `\w` and `\W`. +* Handle/document more attributes in the `[colors]` section of `~/.myclirc`. Bug Fixes diff --git a/mycli/clistyle.py b/mycli/clistyle.py index 9f6d21c4..8e5d4163 100644 --- a/mycli/clistyle.py +++ b/mycli/clistyle.py @@ -104,6 +104,28 @@ def parse_pygments_style( return token_type, style_dict[token_name] +def is_valid_pygments(name: str) -> bool: + try: + + class TestStyle(PygmentsStyle): + default_style = '' + styles = {Token.Default: name} + + return True + except AssertionError: + # can't emit error because some styles are valid pygments and not valid ptoolkit + return False + + +def is_valid_ptoolkit(name: str) -> bool: + try: + _s = Style([("default", name)]) + return True + except ValueError: + # can't emit error because some styles are valid pygments and not valid ptoolkit + return False + + def style_factory_toolkit(name: str, cli_style: dict[str, str]) -> _MergedStyle: try: style: PygmentsStyle = pygments.styles.get_style_by_name(name) @@ -119,14 +141,16 @@ def style_factory_toolkit(name: str, cli_style: dict[str, str]) -> _MergedStyle: 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)) + if is_valid_ptoolkit(style_value): + 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])) + if is_valid_ptoolkit(cli_style[token]): + prompt_styles.append((token, cli_style[token])) override_style: Style = Style([("bottom-toolbar", "noreverse")]) return merge_styles([style_from_pygments_cls(style), override_style, Style(prompt_styles)]) @@ -145,13 +169,16 @@ def style_factory_helpers( for token in cli_style: if token.startswith("Token."): token_type, style_value = parse_pygments_style(token, style, cli_style) - style.update({token_type: style_value}) + if is_valid_pygments(style_value): + 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]}) + if is_valid_pygments(cli_style[token]): + style.update({token_type: cli_style[token]}) elif token in OVERRIDE_STYLE_TO_TOKEN: token_type = OVERRIDE_STYLE_TO_TOKEN[token] - style.update({token_type: cli_style[token]}) + if is_valid_pygments(cli_style[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) diff --git a/mycli/myclirc b/mycli/myclirc index 374e9370..2221707a 100644 --- a/mycli/myclirc +++ b/mycli/myclirc @@ -235,7 +235,10 @@ control_d = exit # possible values: auto, fzf, reverse_isearch control_r = auto -# Custom colors for the completion menu, toolbar, etc. +# Custom colors for the completion menu, toolbar, etc, with actual support +# depending on the terminal, and the property being set. +# Colors: #ffffff, bg:#ffffff, border:#ffffff. +# Attributes: (no)blink, bold, dim, hidden, inherit, italic, reverse, strike, underline. [colors] completion-menu.completion.current = 'bg:#ffffff #000000' completion-menu.completion = 'bg:#008888 #ffffff' diff --git a/test/myclirc b/test/myclirc index 9ff96d8a..4c315fad 100644 --- a/test/myclirc +++ b/test/myclirc @@ -233,7 +233,10 @@ control_d = exit # possible values: auto, fzf, reverse_isearch control_r = auto -# Custom colors for the completion menu, toolbar, etc. +# Custom colors for the completion menu, toolbar, etc, with actual support +# depending on the terminal, and the property being set. +# Colors: #ffffff, bg:#ffffff, border:#ffffff. +# Attributes: (no)blink, bold, dim, hidden, inherit, italic, reverse, strike, underline. [colors] completion-menu.completion.current = "bg:#ffffff #000000" completion-menu.completion = "bg:#008888 #ffffff"