summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/color.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansiblelint/color.py')
-rw-r--r--src/ansiblelint/color.py104
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]