diff --git a/CHANGELOG b/CHANGELOG index 5764c6b..acf7d5c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Changelog +## Version 2.10.0 + +(released on 2026-02-09) + +- Allow TrueColor Pygments formatters, based on the `COLORTERM` env variable. + ## Version 2.9.0 (released on 2026-01-26) diff --git a/cli_helpers/compat.py b/cli_helpers/compat.py index 422403c..2eedfb5 100644 --- a/cli_helpers/compat.py +++ b/cli_helpers/compat.py @@ -36,10 +36,14 @@ HAS_PYGMENTS = True try: from pygments.token import Token - from pygments.formatters.terminal256 import Terminal256Formatter + from pygments.formatters.terminal256 import ( + TerminalTrueColorFormatter, + Terminal256Formatter, + ) except ImportError: HAS_PYGMENTS = False Terminal256Formatter = None + TerminalTrueColorFormatter = None Token = SimpleNamespace() Token.Output = SimpleNamespace() Token.Output.Header = None diff --git a/cli_helpers/tabular_output/tabulate_adapter.py b/cli_helpers/tabular_output/tabulate_adapter.py index bb8f492..5caa55e 100644 --- a/cli_helpers/tabular_output/tabulate_adapter.py +++ b/cli_helpers/tabular_output/tabulate_adapter.py @@ -3,8 +3,15 @@ from __future__ import unicode_literals +import os + from cli_helpers.utils import filter_dict_by_key -from cli_helpers.compat import Terminal256Formatter, Token, StringIO +from cli_helpers.compat import ( + Terminal256Formatter, + TerminalTrueColorFormatter, + Token, + StringIO, +) from .preprocessors import ( convert_to_string, truncate_string, @@ -193,7 +200,10 @@ class YourStyle(Style): """ if style and HAS_PYGMENTS and format_name in supported_table_formats: - formatter = Terminal256Formatter(style=style) + if "truecolor" in os.getenv("COLORTERM", "").lower(): + formatter = TerminalTrueColorFormatter(style=style) + else: + formatter = Terminal256Formatter(style=style) def style_field(token, field): """Get the styled text for a *field* using *token* type.""" diff --git a/cli_helpers/utils.py b/cli_helpers/utils.py index 96e629e..921c2bc 100644 --- a/cli_helpers/utils.py +++ b/cli_helpers/utils.py @@ -2,6 +2,7 @@ """Various utility functions and helpers.""" import binascii +import os import re from functools import lru_cache from typing import Dict @@ -11,7 +12,13 @@ if TYPE_CHECKING: from pygments.style import StyleMeta -from cli_helpers.compat import binary_type, text_type, Terminal256Formatter, StringIO +from cli_helpers.compat import ( + binary_type, + text_type, + Terminal256Formatter, + TerminalTrueColorFormatter, + StringIO, +) def bytes_to_string(b): @@ -112,8 +119,11 @@ def replace(s, replace): @lru_cache() -def _get_formatter(style) -> Terminal256Formatter: - return Terminal256Formatter(style=style) +def _get_formatter(style) -> Terminal256Formatter | TerminalTrueColorFormatter: + if "truecolor" in os.getenv("COLORTERM", "").lower(): + return TerminalTrueColorFormatter(style=style) + else: + return Terminal256Formatter(style=style) def style_field(token, field, style): diff --git a/tests/tabular_output/test_preprocessors.py b/tests/tabular_output/test_preprocessors.py index 4e044a8..214b48f 100644 --- a/tests/tabular_output/test_preprocessors.py +++ b/tests/tabular_output/test_preprocessors.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals from decimal import Decimal +import os import pytest @@ -29,6 +30,12 @@ import types +@pytest.fixture +def TwoFiftySixColor(): + # todo: finalize this fixture by resetting the env value + os.environ["COLORTERM"] = "" + + def test_convert_to_string(): """Test the convert_to_string() function.""" data = [[1, "John"], [2, "Jill"]] @@ -60,7 +67,7 @@ def test_override_missing_values(): @pytest.mark.skipif(not HAS_PYGMENTS, reason="requires the Pygments library") -def test_override_missing_value_with_style(): +def test_override_missing_value_with_style(TwoFiftySixColor): """Test that *override_missing_value()* styles output.""" class NullStyle(Style): @@ -185,7 +192,7 @@ def test_style_output_no_pygments(): @pytest.mark.skipif(not HAS_PYGMENTS, reason="requires the Pygments library") -def test_style_output(): +def test_style_output(TwoFiftySixColor): """Test that *style_output()* styles output.""" class CliStyle(Style): @@ -210,7 +217,7 @@ class CliStyle(Style): @pytest.mark.skipif(not HAS_PYGMENTS, reason="requires the Pygments library") -def test_style_output_with_newlines(): +def test_style_output_with_newlines(TwoFiftySixColor): """Test that *style_output()* styles output with newlines in it.""" class CliStyle(Style): @@ -238,7 +245,7 @@ class CliStyle(Style): @pytest.mark.skipif(not HAS_PYGMENTS, reason="requires the Pygments library") -def test_style_output_custom_tokens(): +def test_style_output_custom_tokens(TwoFiftySixColor): """Test that *style_output()* styles output with custom token names.""" class CliStyle(Style):