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 → │ bold │ dim │ underline │ overline │ italic │ blink │ reverse │ strikethrough │
├───────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┤
│ black │ black │ black │ black │ black │ black │ black │ black │ black │
│ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │
│ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │
│ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │
│ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │
│ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │
│ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │
│ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │
│ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │
│ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │
│ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │
│ green │ green │ green │ green │ green │ green │ green │ green │ green │
│ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │
│ red │ red │ red │ red │ red │ red │ red │ red │ red │
│ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │
│ white │ white │ white │ white │ white │ white │ white │ white │ white │
│ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │
╰───────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────╯
Color matrix¶
$ click-extra --color colors
╭─────────────────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────╮
│ Foreground ↴ \ Background → │ black │ blue │ bright_black │ bright_blue │ bright_cyan │ bright_green │ bright_magenta │ bright_red │ bright_white │ bright_yellow │ cyan │ green │ magenta │ red │ reset │ white │ yellow │
├─────────────────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┼────────────────┤
│ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │ black │
│ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │ blue │
│ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │ bright_black │
│ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │ bright_blue │
│ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │ bright_cyan │
│ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │ bright_green │
│ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │ bright_magenta │
│ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │ bright_red │
│ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │ bright_white │
│ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │ bright_yellow │
│ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │ cyan │
│ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │ green │
│ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │ magenta │
│ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │ red │
│ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │ reset │
│ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │ white │
│ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │ yellow │
╰─────────────────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────╯
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:
HelpThemeExtends
cloup.HelpThemewithlogging.levelsand extra properties.- 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:
- 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
--coloroption 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:
ExtraOptionA 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.
Todo
Support the TERM environment variable convention?
- 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:
objectStructured collection of keywords extracted from a Click context for help screen highlighting.
Each field corresponds to a semantic category with its own styling.
- class click_extra.colorize.ExtraHelpColorsMixin[source]¶
Bases:
objectAdds 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.
- class click_extra.colorize.HelpExtraFormatter(*args, **kwargs)[source]¶
Bases:
HelpFormatterExtends 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
HelpThemeto our ownHelpExtraTheme.- 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:
- click_extra.colorize.highlight(content, patterns, styling_func, ignore_case=False)[source]¶
Highlights parts of the
contentthat matchespatterns.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ßestring matching theStrassecontent.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: