Colored help

Click Extra extends Cloup’s help formatter and theme to automatically colorize every element of the help screen: options, choices, metavars, arguments, CLI and subcommand names, aliases, environment variables, defaults, ranges, and required labels.

Cross-reference highlighting

Option names are highlighted wherever they appear in the help screen, not only in the synopsis column. If an option name shows up in another option’s description or in the command’s docstring, it gets the same styling. This turns plain-text references into visual links, making it easier to scan for related options.

from click_extra import Choice, command, option, echo

@command
@option("--format", type=Choice(["json", "csv"]), help="Output format.")
@option("--output", help="Write to file instead of stdout.")
@option(
    "--dry-run",
    is_flag=True,
    help="Preview what would be written to --output without --format validation.",
)
def export(format, output, dry_run):
    """Export data.

    Combine --format and --output to write directly to a file.
    Use --dry-run to preview without side effects.
    """
    echo("Exporting...")
$ export --help
Usage: export [OPTIONS]

  Export data.

  Combine --format and --output to write directly to a file. Use --dry-run to
  preview without side effects.

Options:
  --format [json|csv]     Output format.
  --output TEXT           Write to file instead of stdout.
  --dry-run               Preview what would be written to --output without
                          --format validation.
  --time / --no-time      Measure and print elapsed execution time.  [default:
                          no-time]
  --color, --ansi / --no-color, --no-ansi
                          Strip out all colors and all ANSI codes from output.
                          [default: color]
  --config CONFIG_PATH    Location of the configuration file. Supports local
                          path with glob patterns or remote URL.  [default: ~/.c
                          onfig/export/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jso
                          nc,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config             Ignore all configuration files and only use command
                          line parameters and environment variables.
  --validate-config FILE  Validate the configuration file and exit.
  --show-params           Show all CLI parameters, their provenance, defaults
                          and value, then exit.
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                          Rendering style of tables.  [default: rounded-outline]
  --verbosity LEVEL       Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                          [default: WARNING]
  -v, --verbose           Increase the default WARNING verbosity by one level
                          for each additional repetition of the option.
                          [default: 0]
  --version               Show the version and exit.
  -h, --help              Show this message and exit.

The same applies to choices (highlighted in the metavar list and in any description that references them), arguments, and subcommand names.

Disabling cross-reference highlighting

If the free-text matching produces false positives (option names or choices that coincide with common words), disable it via the theme:

from click_extra import HelpExtraTheme, group

safe_theme = HelpExtraTheme.dark().with_(cross_ref_highlight=False)


@group(context_settings={"formatter_settings": {"theme": safe_theme}})
def cli(): ...

With cross_ref_highlight=False, only structural elements are styled: bracket fields ([default: ...], [env var: ...], ranges, [required]), deprecated messages, subcommand names in definition lists, and choice metavars ([json|csv|xml]). Option names, choices in free-form text, arguments, metavars, and CLI names in descriptions and docstrings are left unstyled.

Custom keyword injection

Use extra_keywords to inject additional strings for highlighting. Strings are grouped by category in a HelpKeywords dataclass, so each gets the appropriate style:

from click_extra import HelpKeywords, command, echo, option

@command(
    extra_keywords=HelpKeywords(long_options={"--profile"}),
)
@option("--output", help="Write to file. See --profile for timing.")
def build(output):
    """Build the project."""
    echo("Building...")
$ build --help
Usage: build [OPTIONS]

  Build the project.

Options:
  --output TEXT           Write to file. See --profile for timing.
  --time / --no-time      Measure and print elapsed execution time.  [default:
                          no-time]
  --color, --ansi / --no-color, --no-ansi
                          Strip out all colors and all ANSI codes from output.
                          [default: color]
  --config CONFIG_PATH    Location of the configuration file. Supports local
                          path with glob patterns or remote URL.  [default: ~/.c
                          onfig/build/{*.toml,*.yaml,*.yml,*.json,*.json5,*.json
                          c,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config             Ignore all configuration files and only use command
                          line parameters and environment variables.
  --validate-config FILE  Validate the configuration file and exit.
  --show-params           Show all CLI parameters, their provenance, defaults
                          and value, then exit.
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                          Rendering style of tables.  [default: rounded-outline]
  --verbosity LEVEL       Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                          [default: WARNING]
  -v, --verbose           Increase the default WARNING verbosity by one level
                          for each additional repetition of the option.
                          [default: 0]
  --version               Show the version and exit.
  -h, --help              Show this message and exit.

Suppressing keyword highlighting

The mirror of extra_keywords: use excluded_keywords to prevent specific strings from being highlighted, even when they are auto-collected from the Click context:

from click_extra import Choice, HelpKeywords, command, echo, option

@command(
    excluded_keywords=HelpKeywords(choices={"text"}),
)
@option("--format", type=Choice(["json", "text"]), help="Use json or text.")
def export(format):
    """Export data."""
    echo("Exporting...")
$ export --help
Usage: export [OPTIONS]

  Export data.

Options:
  --format [json|text]    Use json or text.
  --time / --no-time      Measure and print elapsed execution time.  [default:
                          no-time]
  --color, --ansi / --no-color, --no-ansi
                          Strip out all colors and all ANSI codes from output.
                          [default: color]
  --config CONFIG_PATH    Location of the configuration file. Supports local
                          path with glob patterns or remote URL.  [default: ~/.c
                          onfig/export/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jso
                          nc,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config             Ignore all configuration files and only use command
                          line parameters and environment variables.
  --validate-config FILE  Validate the configuration file and exit.
  --show-params           Show all CLI parameters, their provenance, defaults
                          and value, then exit.
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                          Rendering style of tables.  [default: rounded-outline]
  --verbosity LEVEL       Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                          [default: WARNING]
  -v, --verbose           Increase the default WARNING verbosity by one level
                          for each additional repetition of the option.
                          [default: 0]
  --version               Show the version and exit.
  -h, --help              Show this message and exit.

Excluded keywords are only suppressed in free-text descriptions and docstrings. They remain styled inside their own choice metavar, which is a structural element (like bracket fields).

Exclusions propagate from parent groups to subcommands. If a group excludes a choice, that exclusion applies to all nested subcommand help screens too. Parent and child exclusions are merged, so you can exclude additional keywords at any level:

from click_extra import Choice, HelpKeywords, echo, group, option

@group(excluded_keywords=HelpKeywords(choices={"version"}))
@option("--sort-by", type=Choice(["name", "version"]))
def cli(sort_by):
    """Sort items."""

@cli.command()
def show():
    """Show the version of each item."""
    echo("Showing...")
$ cli show --help
Usage: cli show [OPTIONS]

  Show the version of each item.

Options:
  -h, --help  Show this message and exit.

Both extra_keywords and excluded_keywords accept a HelpKeywords instance. The available category fields are: cli_names, subcommands, command_aliases, arguments, long_options, short_options, choices, choice_metavars, metavars, envvars, and defaults. The choice_metavars field is auto-populated from click.Choice parameters and rarely needs manual specification.

For advanced customization, override collect_keywords() on your command class. Call super() and mutate the returned HelpKeywords to add or remove entries:

from click_extra import ExtraCommand, HelpKeywords


class MyCommand(ExtraCommand):
    def collect_keywords(self, ctx):
        kw = super().collect_keywords(ctx)
        kw.choices.discard("internal")
        kw.long_options.add("--undocumented-flag")
        return kw

Bracket fields

Trailing metadata brackets ([default: ...], [env var: ...], [required], and range expressions) each get their own style. All four fields can appear together:

from click_extra import command, option, IntRange

@command
@option(
    "--threshold",
    type=IntRange(1, 100),
    default=50,
    required=True,
    show_default=True,
    envvar="THRESHOLD",
    show_envvar=True,
    help="Sensitivity level.",
)
def analyze(threshold):
    """Run analysis."""
$ analyze --help
Usage: analyze [OPTIONS]

  Run analysis.

Options:
  --threshold INTEGER RANGE  Sensitivity level.  [env var: THRESHOLD,
                             ANALYZE_THRESHOLD; default: 50; 1<=x<=100;
                             required]
  --time / --no-time         Measure and print elapsed execution time.
                             [default: no-time]
  --color, --ansi / --no-color, --no-ansi
                             Strip out all colors and all ANSI codes from
                             output.  [default: color]
  --config CONFIG_PATH       Location of the configuration file. Supports local
                             path with glob patterns or remote URL.  [default: ~
                             /.config/analyze/{*.toml,*.yaml,*.yml,*.json,*.json
                             5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config                Ignore all configuration files and only use command
                             line parameters and environment variables.
  --validate-config FILE     Validate the configuration file and exit.
  --show-params              Show all CLI parameters, their provenance, defaults
                             and value, then exit.
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                             Rendering style of tables.  [default: rounded-
                             outline]
  --verbosity LEVEL          Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                             [default: WARNING]
  -v, --verbose              Increase the default WARNING verbosity by one level
                             for each additional repetition of the option.
                             [default: 0]
  --version                  Show the version and exit.
  -h, --help                 Show this message and exit.

Note

When choices are Enum members, Click Extra colorizes their name attribute (not their value), matching Click’s own behavior. Use EnumChoice if you need user-friendly choice strings based on values or custom representations.

Why not use rich-click?

rich-click is a good project that aims to integrate Rich with Click. Like Click Extra, it provides a ready-to-use help formatter for Click.

But contrary to Click Extra, the help screen is rendered within a table, which takes the whole width of the terminal. This is not ideal if you try to print the output of a command somewhere else.

The typical use-case is users reporting issues on GitHub, and pasting the output of a command in the issue description. If the output is too wide, it will be akwardly wrapped, or adds a horizontal scrollbar to the page.

Without a table imposing a maximal width, the help screens from Click Extra will be rendered with the minimal width of the text, and will be more readable.

Hint

This is just a matter of preference, as nothing prevents you to use both rich-click and Click Extra in the same project, and get the best from both.

--color/--no-color flag

Click Extra adds a --color/--no-color flag (aliased as --ansi/--no-ansi) that controls whether ANSI codes are emitted. It is eager, so it takes effect before other eager options like --version.

The option respects the NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables. When any of these signals “no color”, the environment takes precedence over the default value (but an explicit --color or --no-color on the command line always wins).

All Click Extra commands and groups include this option by default. Use color_option as a standalone decorator when building CLIs with plain click.command:

import click
from click_extra import echo, color_option

@click.command
@color_option
def greet():
    """Say hello with optional color."""
    ctx = click.get_current_context()
    if ctx.color:
        echo("\x1b[32mHello in green!\x1b[0m")
    else:
        echo("Hello without color.")
$ greet --color
Hello in green!
$ greet --no-color
Hello without color.

--help, -h aliases

Click Extra defaults help_option_names to ("--help", "-h"), adding the short -h alias that Click does not provide out of the box. This applies to all commands and groups created with Click Extra decorators:

from click_extra import command, echo

@command
def hello():
    """Greet the user."""
    echo("Hello!")
$ hello -h
Usage: hello [OPTIONS]

  Greet the user.

Options:
  --time / --no-time      Measure and print elapsed execution time.  [default:
                          no-time]
  --color, --ansi / --no-color, --no-ansi
                          Strip out all colors and all ANSI codes from output.
                          [default: color]
  --config CONFIG_PATH    Location of the configuration file. Supports local
                          path with glob patterns or remote URL.  [default: ~/.c
                          onfig/hello/{*.toml,*.yaml,*.yml,*.json,*.json5,*.json
                          c,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config             Ignore all configuration files and only use command
                          line parameters and environment variables.
  --validate-config FILE  Validate the configuration file and exit.
  --show-params           Show all CLI parameters, their provenance, defaults
                          and value, then exit.
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                          Rendering style of tables.  [default: rounded-outline]
  --verbosity LEVEL       Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                          [default: WARNING]
  -v, --verbose           Increase the default WARNING verbosity by one level
                          for each additional repetition of the option.
                          [default: 0]
  --version               Show the version and exit.
  -h, --help              Show this message and exit.

Colors and styles

The click-extra demo subcommands render matrices of all colors, styles, and palettes, useful for testing terminal capabilities. Based on cloup.styling.Style:

Style matrix

$ click-extra --color styles
╭───────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────╮
│ Color ↴ \ Style → │ bolddimunderlineoverlineitalicblinkreversestrikethrough  │
├───────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┤
│ blackblackblackblackblackblackblackblackblack          │
│ blueblueblueblueblueblueblueblueblue           │
│ bright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_black   │
│ bright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_blue    │
│ bright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyan    │
│ bright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_green   │
│ bright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magenta │
│ bright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_red     │
│ bright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_white   │
│ bright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellow  │
│ cyancyancyancyancyancyancyancyancyan           │
│ greengreengreengreengreengreengreengreengreen          │
│ magentamagentamagentamagentamagentamagentamagentamagentamagenta        │
│ redredredredredredredredred            │
│ reset             │ resetresetresetresetresetresetresetreset          │
│ whitewhitewhitewhitewhitewhitewhitewhitewhite          │
│ yellowyellowyellowyellowyellowyellowyellowyellowyellow         │
╰───────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────╯

Color matrix

$ click-extra --color colors
╭─────────────────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────╮
│ Foreground ↴ \ Background → │ blackbluebright_blackbright_bluebright_cyanbright_greenbright_magentabright_redbright_whitebright_yellowcyangreenmagentared            │ reset          │ whiteyellow         │
├─────────────────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┤
│ blackblackblackblackblackblackblackblackblackblackblackblackblackblackblackblackblackblack          │
│ blueblueblueblueblueblueblueblueblueblueblueblueblueblueblueblueblueblue           │
│ bright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_blackbright_black   │
│ bright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_bluebright_blue    │
│ bright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyanbright_cyan    │
│ bright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_greenbright_green   │
│ bright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magentabright_magenta │
│ bright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_redbright_red     │
│ bright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_whitebright_white   │
│ bright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellowbright_yellow  │
│ cyancyancyancyancyancyancyancyancyancyancyancyancyancyancyancyancyancyan           │
│ greengreengreengreengreengreengreengreengreengreengreengreengreengreengreengreengreengreen          │
│ magentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagentamagenta        │
│ redredredredredredredredredredredredredredredredredred            │
│ reset                       │ resetresetresetresetresetresetresetresetresetresetresetresetresetreset          │ reset          │ resetreset          │
│ whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite          │
│ yellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellowyellow         │
╰─────────────────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────╯

256-color indexed palette

$ click-extra --color palette
  +  0 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435
  0 
 16 
 52 
 88 
124 
160 
196 
232 

8-color foreground/background combinations

$ click-extra --color 8color
            40   41   42   43   44   45   46   47  
   30  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;30  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   31  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;31  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   32  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;32  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   33  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;33  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   34  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;34  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   35  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;35  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   36  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;36  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
   37  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 
 1;37  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw  gYw 

24-bit RGB vs. 256-color quantization

$ click-extra --color gradient
Rainbow:
  24-bit ████████████████████████████████████████████████████████████████████
   8-bit ████████████████████████████████████████████████████████████████████

Grayscale:
  24-bit ██████████████████████████████████████████████████████████████████████
   8-bit ██████████████████████████████████████████████████████████████████████

Red:
  24-bit ████████████████████████████████████████████████████████████████████████
   8-bit ████████████████████████████████████████████████████████████████████████

Cyan:
  24-bit ████████████████████████████████████████████████████████████████████████
   8-bit ████████████████████████████████████████████████████████████████████████

Caution

The rendering of colors and styles in this HTML documentation is not complete, and does not reflect the real output in a terminal. Some SGR attributes (like reverse video) have no direct CSS equivalent and are not rendered. Some terminal emulators also lack support for overline (SGR 53), blink (SGR 5), and strikethrough (SGR 9).

Tip

Run uvx click-extra styles in your terminal to see the real rendering with your color scheme.

click_extra.colorize API

        classDiagram
  ExtraOption <|-- ColorOption
  HelpFormatter <|-- HelpExtraFormatter
  HelpTheme <|-- HelpExtraTheme
    

Helpers and utilities to apply ANSI coloring to terminal content.

Note

_nearest_256 (24-bit RGB to 256-color quantization) lives here rather than in pygments.py because both cli.py and pygments.py need it, and pygments.py is gated behind the optional pygments extra. Placing it in colorize.py (which has no optional dependencies) keeps the function available to the CLI regardless of whether Pygments is installed.

class click_extra.colorize.HelpExtraTheme(invoked_command=<function identity>, command_help=<function identity>, heading=<function identity>, constraint=<function identity>, section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=<function identity>, alias_secondary=None, epilog=<function identity>, critical=<function identity>, error=<function identity>, warning=<function identity>, info=<function identity>, debug=<function identity>, option=<function identity>, subcommand=<function identity>, choice=<function identity>, metavar=<function identity>, bracket=<function identity>, envvar=<function identity>, default=<function identity>, range_label=<function identity>, required=<function identity>, argument=<function identity>, deprecated=<function identity>, search=<function identity>, success=<function identity>, cross_ref_highlight=True, subheading=<function identity>)[source]

Bases: HelpTheme

Extends cloup.HelpTheme with logging.levels and extra properties.

critical()
Return type:

TypeVar(T)

error()
Return type:

TypeVar(T)

warning()
Return type:

TypeVar(T)

info()
Return type:

TypeVar(T)

debug()

Log levels from Python’s logging module.

Return type:

TypeVar(T)

option()
Return type:

TypeVar(T)

subcommand()
Return type:

TypeVar(T)

choice()
Return type:

TypeVar(T)

metavar()
Return type:

TypeVar(T)

bracket()
Return type:

TypeVar(T)

envvar()
Return type:

TypeVar(T)

default()
Return type:

TypeVar(T)

range_label()
Return type:

TypeVar(T)

required()
Return type:

TypeVar(T)

argument()
Return type:

TypeVar(T)

deprecated()
Return type:

TypeVar(T)

search()
Return type:

TypeVar(T)

success()

Click Extra new coloring properties.

Return type:

TypeVar(T)

cross_ref_highlight: bool = True

Highlight options, choices, arguments, metavars and CLI names in free-form text (descriptions, docstrings).

When False, only structural elements are styled: bracket fields ([default: ...], [env var: ...], ranges, [required]), deprecated messages, and subcommand names in definition lists.

subheading()

Non-canonical Click Extra properties.

Note

Subheading is used for sub-sections, like in the help of mail-deduplicate.

Todo

Maybe this shouldn’t be in Click Extra because it is a legacy inheritance from one of my other project.

Return type:

TypeVar(T)

with_(**kwargs)[source]

Derives a new theme from the current one, with some styles overridden.

Returns the same instance if the provided styles are the same as the current.

Return type:

HelpExtraTheme

static dark()[source]

A theme assuming a dark terminal background color.

Return type:

HelpExtraTheme

static light()[source]

A theme assuming a light terminal background color.

Todo

Tweak colors to make them more readable.

Return type:

HelpExtraTheme

click_extra.colorize.default_theme: HelpExtraTheme = HelpExtraTheme(invoked_command=Style(fg='bright_white', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'bright_white', 'bg': None, 'bold': None, 'dim': None, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), command_help=<function identity>, heading=Style(fg='bright_blue', bg=None, bold=True, dim=None, underline=True, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'bright_blue', 'bg': None, 'bold': True, 'dim': None, 'underline': True, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), constraint=Style(fg='magenta', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg='cyan', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), alias_secondary=Style(fg='cyan', bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), epilog=<function identity>, critical=Style(fg='red', bg=None, bold=True, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), error=Style(fg='red', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'red', 'bg': None, 'bold': None, 'dim': None, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), warning=Style(fg='yellow', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), info=<function identity>, debug=Style(fg='blue', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), option=Style(fg='cyan', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'cyan', 'bg': None, 'bold': None, 'dim': None, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), subcommand=Style(fg='cyan', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), choice=Style(fg='magenta', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'magenta', 'bg': None, 'bold': None, 'dim': None, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), metavar=Style(fg='cyan', bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'cyan', 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), bracket=Style(fg=None, bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': None, 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), envvar=Style(fg='yellow', bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'yellow', 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), default=Style(fg='green', bg=None, bold=None, dim=True, underline=None, overline=None, italic=True, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'green', 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': True, 'blink': None, 'reverse': None, 'strikethrough': None}), range_label=Style(fg='cyan', bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'cyan', 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), required=Style(fg='red', bg=None, bold=None, dim=True, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'red', 'bg': None, 'bold': None, 'dim': True, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), argument=Style(fg='cyan', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), deprecated=Style(fg='bright_yellow', bg=None, bold=True, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), search=Style(fg='green', bg=None, bold=True, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None), success=Style(fg='green', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs={'fg': 'green', 'bg': None, 'bold': None, 'dim': None, 'underline': None, 'overline': None, 'italic': None, 'blink': None, 'reverse': None, 'strikethrough': None}), cross_ref_highlight=True, subheading=Style(fg='blue', bg=None, bold=None, dim=None, underline=None, overline=None, italic=None, blink=None, reverse=None, strikethrough=None, text_transform=None, _style_kwargs=None))

Default color theme for Click Extra.

click_extra.colorize.nocolor_theme: HelpExtraTheme = HelpExtraTheme(invoked_command=<function identity>, command_help=<function identity>, heading=<function identity>, constraint=<function identity>, section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=<function identity>, alias_secondary=None, epilog=<function identity>, critical=<function identity>, error=<function identity>, warning=<function identity>, info=<function identity>, debug=<function identity>, option=<function identity>, subcommand=<function identity>, choice=<function identity>, metavar=<function identity>, bracket=<function identity>, envvar=<function identity>, default=<function identity>, range_label=<function identity>, required=<function identity>, argument=<function identity>, deprecated=<function identity>, search=<function identity>, success=<function identity>, cross_ref_highlight=True, subheading=<function identity>)

Color theme for Click Extra to force no colors.

click_extra.colorize.KO = '\x1b[31m✘\x1b[0m'

Pre-rendered UI-elements.

click_extra.colorize.color_envvars = {'CLICOLOR': True, 'CLICOLORS': True, 'CLICOLORS_FORCE': True, 'CLICOLOR_FORCE': True, 'COLOR': True, 'COLORS': True, 'FORCE_COLOR': True, 'FORCE_COLORS': True, 'LLM': False, 'NOCOLOR': False, 'NOCOLORS': False, 'NO_COLOR': False, 'NO_COLORS': False}

List of environment variables recognized as flags to switch color rendering on or off.

The key is the name of the variable and the boolean value the value to pass to --color option flag when encountered.

Source:

class click_extra.colorize.ColorOption(param_decls=None, is_flag=True, default=True, is_eager=True, expose_value=False, help='Strip out all colors and all ANSI codes from output.', **kwargs)[source]

Bases: ExtraOption

A pre-configured option that is adding a --color/--no-color (aliased by --ansi/--no-ansi) to keep or strip colors and ANSI codes from CLI output.

This option is eager by default to allow for other eager options (like --version) to be rendered colorless.

Todo

Should we switch to --color=<auto|never|always> as GNU tools does?

Also see how the isatty property defaults with this option, and how it can be implemented in Python.

static disable_colors(ctx, param, value)[source]

Callback disabling all coloring utilities.

Re-inspect the environment for existence of colorization flags to re-interpret the provided value.

Return type:

None

class click_extra.colorize.HelpKeywords(cli_names=<factory>, subcommands=<factory>, command_aliases=<factory>, arguments=<factory>, long_options=<factory>, short_options=<factory>, choices=<factory>, choice_metavars=<factory>, metavars=<factory>, envvars=<factory>, defaults=<factory>)[source]

Bases: object

Structured collection of keywords extracted from a Click context for help screen highlighting.

Each field corresponds to a semantic category with its own styling.

cli_names: set[str]
subcommands: set[str]
command_aliases: set[str]
arguments: set[str]
long_options: set[str]
short_options: set[str]
choices: set[str]
choice_metavars: set[str]
metavars: set[str]
envvars: set[str]
defaults: set[str]
merge(other)[source]

Merge another HelpKeywords into this one.

Each set field is updated with the corresponding set from other.

Return type:

None

subtract(other)[source]

Remove keywords found in other from this instance.

Each set field is difference-updated with the corresponding set from other. Mirror of merge().

Return type:

None

class click_extra.colorize.ExtraHelpColorsMixin[source]

Bases: object

Adds extra-keywords highlighting to Click commands.

This mixin for click.Command-like classes intercepts the top-level helper- generation method to initialize the formatter with dynamic settings. This is implemented at this stage so we have access to the global context.

extra_keywords: HelpKeywords | None = None

Extra keywords to merge into the auto-collected set. Consumers can set this attribute on a command instance to inject additional keywords for help screen highlighting (e.g. placeholder option names like --<manager-id> that appear in prose but are not real parameters).

excluded_keywords: HelpKeywords | None = None

Keywords to remove from the auto-collected set. Mirror of extra_keywords: any string listed here will not be highlighted even if it was collected from the Click context.

collect_keywords(ctx)[source]

Parse click context to collect option names, choices and metavar keywords.

Override this method to customize keyword collection. Call super() and mutate the returned HelpKeywords to extend the default set.

Return type:

HelpKeywords

get_help(ctx)[source]

Replace default formatter by our own.

Return type:

str

format_help(ctx, formatter)[source]

Feed our custom formatter instance with the keywords to highlight.

Return type:

None

class click_extra.colorize.HelpExtraFormatter(*args, **kwargs)[source]

Bases: HelpFormatter

Extends Cloup’s custom HelpFormatter to highlights options, choices, metavars and default values.

This is being discussed for upstream integration at:

Forces theme to our default.

Also transform Cloup’s standard HelpTheme to our own HelpExtraTheme.

theme: HelpExtraTheme
keywords: HelpKeywords = HelpKeywords(cli_names=set(), subcommands=set(), command_aliases=set(), arguments=set(), long_options=set(), short_options=set(), choices=set(), choice_metavars=set(), metavars=set(), envvars=set(), defaults=set())
excluded_keywords: HelpKeywords | None = None
highlight_extra_keywords(help_text)[source]

Highlight extra keywords in help screens based on the theme.

Uses the highlight() function for all keyword categories. Each category is processed as a batch of regex patterns with a single styling function, which handles overlapping matches and prevents double-styling.

Return type:

str

getvalue()[source]

Wrap original Click.HelpFormatter.getvalue() to force extra-colorization on rendering.

Return type:

str

click_extra.colorize.highlight(content, patterns, styling_func, ignore_case=False)[source]

Highlights parts of the content that matches patterns.

Takes care of overlapping parts within the content, so that the styling function is applied only once to each contiguous range of matching characters.

Todo

Support case-foldeing, so we can have the Straße string matching the Strasse content.

This could be tricky as it messes with string length and characters index, which our logic relies on.

Danger

Roundtrip through lower-casing/upper-casing is a can of worms, because some characters change length when their case is changed:

Return type:

str