diff options
Diffstat (limited to 'src/ansiblelint/color.py')
-rw-r--r-- | src/ansiblelint/color.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/ansiblelint/color.py b/src/ansiblelint/color.py new file mode 100644 index 0000000..8f31e1c --- /dev/null +++ b/src/ansiblelint/color.py @@ -0,0 +1,104 @@ +"""Console coloring and terminal support.""" +from __future__ import annotations + +from typing import Any + +import rich +import rich.markdown +from rich.console import Console +from rich.default_styles import DEFAULT_STYLES +from rich.style import Style +from rich.syntax import Syntax +from rich.theme import Theme + +# WARNING: When making style changes, be sure you test the output of +# `ansible-lint -L` on multiple terminals with dark/light themes, including: +# - iTerm2 (macOS) - bold might not be rendered differently +# - vscode integrated terminal - bold might not be rendered differently, links will not work +# +# When it comes to colors being used, try to match: +# - Ansible official documentation theme, https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html +# - VSCode Ansible extension for syntax highlighting +# - GitHub markdown theme +# +# Current values: (docs) +# codeblock border: #404040 +# codeblock background: #edf0f2 +# codeblock comment: #6a737d (also italic) +# teletype-text: #e74c3c (red) +# teletype-text-border: 1px solid #e1e4e5 (background white) +# text: #404040 +# codeblock other-text: #555555 (black-ish) +# codeblock property: #22863a (green) +# codeblock integer: 032f62 (blue) +# codeblock command: #0086b3 (blue) - [shell] +# == python == +# class: #445588 (dark blue and bold) +# docstring: #dd1144 (red) +# self: #999999 (light-gray) +# method/function: #990000 (dark-red) +# number: #009999 cyan +# keywords (def,None,False,len,from,import): #007020 (green) bold +# super|dict|print: #0086b3 light-blue +# __name__: #bb60d5 (magenta) +# string: #dd1144 (light-red) +DEFAULT_STYLES.update( + { + "markdown.code": Style(color="bright_black"), + "markdown.code_block": Style(dim=True, color="cyan"), + }, +) + + +_theme = Theme( + { + "info": "cyan", + "warning": "yellow", + "danger": "bold red", + "title": "yellow", + "error": "bright_red", + "filename": "blue", + }, +) +console_options: dict[str, Any] = {"emoji": False, "theme": _theme, "soft_wrap": True} +console_options_stderr = console_options.copy() +console_options_stderr["stderr"] = True + +console = rich.get_console() +console_stderr = Console(**console_options_stderr) + + +def reconfigure(new_options: dict[str, Any]) -> None: + """Reconfigure console options.""" + console_options = new_options # pylint: disable=redefined-outer-name + rich.reconfigure(**new_options) + # see https://github.com/willmcgugan/rich/discussions/484#discussioncomment-200182 + new_console_options_stderr = console_options.copy() + new_console_options_stderr["stderr"] = True + tmp_console = Console(**new_console_options_stderr) + console_stderr.__dict__ = tmp_console.__dict__ + + +def render_yaml(text: str) -> Syntax: + """Colorize YAMl for nice display.""" + return Syntax(text, "yaml", theme="ansi_dark") + + +# pylint: disable=redefined-outer-name,unused-argument +def _rich_codeblock_custom_rich_console( + self: rich.markdown.CodeBlock, + console: Console, # noqa: ARG001 + options: rich.console.ConsoleOptions, # noqa: ARG001 +) -> rich.console.RenderResult: # pragma: no cover + code = str(self.text).rstrip() + syntax = Syntax( + code, + self.lexer_name, + theme=self.theme, + word_wrap=True, + background_color="default", + ) + yield syntax + + +rich.markdown.CodeBlock.__rich_console__ = _rich_codeblock_custom_rich_console # type: ignore[method-assign] |