Themes

Click Extra exposes a small theming system that controls every color used in help screens: options, choices, metavars, arguments, CLI names, defaults, environment variables, log levels, and more. Two themes ship by default (dark and light), and downstream projects can register their own.

The --theme option

Every command and group built with @click_extra.command / @click_extra.group automatically gets a --theme flag, alongside the other default options.

from click_extra import command, echo

@command
def weather():
    """Show the local weather forecast."""
    echo("Sunny, 22°C.")
$ weather --theme light --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

The flag is eager, so it is processed before any other option and before help is rendered. The picked theme is stored on the active Click context’s meta dict under click_extra.context.THEME and inherits down to subcommands, so a parent group’s --theme applies to every child. See the available keys table for the full inventory you can read from your own callbacks.

Automatic background detection

Pass --theme=auto to pick between the built-in dark and light palettes from the terminal’s background, mirroring --color=auto. Every Click Extra CLI accepts it, no extra wiring required:

$ weather --theme auto --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

Detection reads two environment variables and uses the first that resolves:

  1. CLITHEME follows the cli-theme convention. A dark or light value (optionally a mode:variant like dark:solarized) is a deliberate override and wins outright; auto falls through.

  2. COLORFGBG is set by a few terminals (rxvt, Konsole) and cached by shell-term-background at shell startup; the background is the last ;-separated field. It is read last because it is frequently stale: it reflects the value when the terminal launched and is not refreshed when you switch themes.

When none of them resolves, auto falls back to dark, so Click Extra’s default is preserved. The --theme default itself stays dark: a CLI that never asks for auto renders exactly as before, and auto is accepted but kept out of the --help metavar.

To make detection the effective default for your CLI, set theme = "auto" in your config file the same way you would pin any other palette:

[weather]
theme = "auto"

Querying the terminal directly

The environment variables above only help if something already populated them. To detect the background on terminals that set none of them, Click Extra can ask the terminal directly with an xterm OSC 11 query: it writes an escape sequence and reads the background color back. This is opt-in because it reads stdin (which can interfere with a CLI that consumes stdin itself) and only works on POSIX terminals.

Enable it by swapping the default --theme option for a ThemeOption built with query_background=True:

from click_extra import command, echo
from click_extra.commands import default_params
from click_extra.theme import ThemeOption

forecast_params = [
    ThemeOption(default="auto", query_background=True)
    if isinstance(param, ThemeOption)
    else param
    for param in default_params()
]

@command(params=forecast_params)
def forecast():
    """Show the weekly forecast."""
    echo("Rain on Thursday.")
$ forecast --help
Usage: forecast [OPTIONS]

  Show the weekly forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/forecast/{*.toml,*.yaml,*.yml
                               ,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pypro
                               ject.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               auto]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

forecast now defaults to the detected theme: absent a CLITHEME override, it runs the live query, which outranks the possibly-stale COLORFGBG, and only falls back to dark when neither settles the question. The query is a no-op when stdin or stdout is not a terminal (a pipe, a file, a captured test stream), so non-interactive runs are unaffected.

Caution

Background detection through COLORFGBG or the live query is best-effort. COLORFGBG is often missing or stale; terminal multiplexers (tmux, screen) cache or mangle the OSC 11 reply; and the query reads stdin. When the choice has to be deterministic, set --theme explicitly (on the command line or in your config file), or export CLITHEME.

The same dark-or-light question turns up across the ecosystem, split along the same environment-variable-versus-live-query line. shell-term-background (POSIX shell) and its Python reader term-background cache the answer into COLORFGBG, while the Rust crates terminal-light, termbg and terminal-colorsaurus query OSC 10/11 directly (the last two also read the Windows console).

Configuration file

Like every other default option, --theme reads its value from pyproject.toml:

[tool.weather]
theme = "light"

Now invocations of the weather CLI pick up the light theme without passing --theme on the command line.

Built-in themes

Name

Color model

Notes

dark

16 named ANSI colors

Process-wide default. Follows the user’s terminal palette.

light

16 named ANSI colors

Tuned for white backgrounds: no bright variants, blue replaces cyan.

solarized_dark

24-bit RGB

Warm-toned dark theme with selective accent contrast.

dracula

24-bit RGB

High-contrast dark theme with vivid neon accents.

nord

24-bit RGB

Cool-toned dark theme built around frost-blue and aurora accents.

monokai

24-bit RGB

Classic dark theme with high-saturation magenta and lime accents.

manpage

None (monochrome)

Bold literals, italic replaceable, no color. Shadows a man page.

Each row is keyed by the --theme choice value; access the instance via BUILTIN_THEMES["<name>"] (like BUILTIN_THEMES["dark"]). Click any name to jump to that theme’s palette listing below.

Click each tab below for a live render of the theme applied to the same weather CLI’s --help output. Colors are produced at Sphinx build time, not screenshots.

$ weather --theme dark --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme light --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme solarized_dark --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme dracula --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme nord --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme monokai --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.
$ weather --theme manpage --help
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

Three flavors ship in click_extra/themes.toml:

  • ANSI themes (dark, light) use the 16 named ANSI colors via cloup.styling.Color, so the rendered colors track whatever palette the user’s terminal is configured with. Pick these when you want to blend in with the user’s terminal theme.

  • Branded themes (solarized_dark, dracula, nord, monokai) emit 24-bit RGB triplets from each theme’s canonical palette. Pick these when the theme name implies specific colors (solarized_dark should look like Solarized, not “whatever the terminal calls cyan”). On a terminal that does not advertise truecolor, click-extra downsamples each triplet to the nearest 256-color cell itself rather than leaving the conversion to the terminal: the choice is optimistic, keeping 24-bit unless COLORTERM is set to an explicit non-truecolor value or TERM ends in -16color (see click_extra.styling.supports_truecolor). Each theme’s slot mapping is hand-curated: there’s no automated translation from generic color-scheme formats, because none of them expose the same semantic roles we care about (option, metavar, choice, deprecated, envvar, …).

  • Monochrome theme (manpage) uses no color at all: it renders literal tokens bold and replaceable tokens italic, the way man-pages(7) typesets a command. Pick it for low-color terminals, screenshots, or output meant to read like a man page. The bold/italic split is the one in literal and replaceable slots.

click_extra.theme.BUILTIN_THEMES is a dict[str, HelpTheme] mapping the names above to their instances; it is built by parsing click_extra/themes.toml at import time and is seeded into theme_registry immediately afterwards. Read the TOML file directly for the exact palette mapping, or call theme.to_dict() at runtime to get a TOML/JSON-friendly dict.

Note

Some standalone-binary builders (Nuitka, PyInstaller) and trimmed downstream packages omit package data files, dropping click_extra/themes.toml. The file is then loaded leniently rather than aborting the import: click-extra logs a warning, leaves BUILTIN_THEMES empty, and keeps the colorless nocolor_theme as the default. CLIs stay usable, and you can still define your own palettes in a [tool.<cli>.themes.<name>] config table (see Themes from your config file below); only the built-in palettes are missing until the data file is restored. For Nuitka, bundle it with --include-package-data=click_extra.

Palettes

Every styled slot of each built-in theme, with the swatch and attribute decorations rendered live from the shipped themes.toml at Sphinx build time. The block below iterates BUILTIN_THEMES and calls palette_html() for each: downstream projects with their own custom themes can drop the same loop into their own docs to get matching swatch listings.

dark

invoked_command
bright_white bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
bright_blue underline
Options:
constraint
magenta
(mutually exclusive)
alias
cyan bold
  show, ls     Show the current state.
alias_secondary
cyan bold dim
  show (ls)     Show the current state.
critical
red bold
CRITICAL: Database connection lost.
error
red
ERROR: Configuration file not found.
warning
yellow
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
blue
DEBUG: Resolved /etc/myapp/config.toml.
option
cyan bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
cyan bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
magenta bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
cyan dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
dim
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
yellow dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
green dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
cyan dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
red dim
--token TEXT    Authentication token.  [required]
argument
cyan italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
bright_yellow
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
green
--retry-budget INTEGER    The retry budget.
success
green
 database migration completed
 1,245 records imported
subheading
blue
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

dracula

invoked_command
#f8f8f2 bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
#ff79c6 underline
Options:
constraint
#ff79c6
(mutually exclusive)
alias
#8be9fd bold
  show, ls     Show the current state.
alias_secondary
#8be9fd bold dim
  show (ls)     Show the current state.
critical
#ff5555 bold
CRITICAL: Database connection lost.
error
#ff5555
ERROR: Configuration file not found.
warning
#ffb86c
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
#6272a4
DEBUG: Resolved /etc/myapp/config.toml.
option
#bd93f9 bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
#bd93f9 bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
#ff79c6 bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
#bd93f9 dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
#6272a4
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
#ffb86c dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
#50fa7b dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
#bd93f9 dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
#ff5555 dim
--token TEXT    Authentication token.  [required]
argument
#bd93f9 italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
#ffb86c
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
#f1fa8c
--retry-budget INTEGER    The retry budget.
success
#50fa7b
 database migration completed
 1,245 records imported
subheading
#8be9fd
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

light

invoked_command
black bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
magenta underline
Options:
constraint
magenta
(mutually exclusive)
alias
blue bold
  show, ls     Show the current state.
alias_secondary
blue bold dim
  show (ls)     Show the current state.
critical
red bold
CRITICAL: Database connection lost.
error
red
ERROR: Configuration file not found.
warning
magenta
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
blue dim
DEBUG: Resolved /etc/myapp/config.toml.
option
blue bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
blue bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
magenta bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
blue dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
dim
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
magenta dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
green dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
blue dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
red dim
--token TEXT    Authentication token.  [required]
argument
blue italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
red
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
green
--retry-budget INTEGER    The retry budget.
success
green
 database migration completed
 1,245 records imported
subheading
blue dim
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

manpage

invoked_command
bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
underline
Options:
alias
bold
  show, ls     Show the current state.
alias_secondary
bold
  show (ls)     Show the current state.
option
bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
argument
italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]

monokai

invoked_command
#f8f8f2 bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
#a6e22e underline
Options:
constraint
#ae81ff
(mutually exclusive)
alias
#a6e22e bold
  show, ls     Show the current state.
alias_secondary
#a6e22e bold dim
  show (ls)     Show the current state.
critical
#f92672 bold
CRITICAL: Database connection lost.
error
#f92672
ERROR: Configuration file not found.
warning
#fd971f
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
#75715e
DEBUG: Resolved /etc/myapp/config.toml.
option
#66d9ef bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
#66d9ef bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
#ae81ff bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
#66d9ef dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
#75715e
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
#fd971f dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
#e6db74 dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
#66d9ef dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
#f92672 dim
--token TEXT    Authentication token.  [required]
argument
#66d9ef italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
#fd971f
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
#e6db74
--retry-budget INTEGER    The retry budget.
success
#a6e22e
 database migration completed
 1,245 records imported
subheading
#a6e22e
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

nord

invoked_command
#eceff4 bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
#5e81ac underline
Options:
constraint
#b48ead
(mutually exclusive)
alias
#8fbcbb bold
  show, ls     Show the current state.
alias_secondary
#8fbcbb bold dim
  show (ls)     Show the current state.
critical
#bf616a bold
CRITICAL: Database connection lost.
error
#bf616a
ERROR: Configuration file not found.
warning
#d08770
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
#4c566a
DEBUG: Resolved /etc/myapp/config.toml.
option
#81a1c1 bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
#81a1c1 bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
#b48ead bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
#81a1c1 dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
#4c566a
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
#d08770 dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
#a3be8c dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
#81a1c1 dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
#bf616a dim
--token TEXT    Authentication token.  [required]
argument
#81a1c1 italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
#d08770
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
#ebcb8b
--retry-budget INTEGER    The retry budget.
success
#a3be8c
 database migration completed
 1,245 records imported
subheading
#88c0d0
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

solarized_dark

invoked_command
#eee8d5 bold
Usage: my-cli [OPTIONS] COMMAND [ARGS]...
heading
#6c71c4 underline
Options:
constraint
#6c71c4
(mutually exclusive)
alias
#2aa198 bold
  show, ls     Show the current state.
alias_secondary
#2aa198 bold dim
  show (ls)     Show the current state.
critical
#dc322f bold
CRITICAL: Database connection lost.
error
#dc322f
ERROR: Configuration file not found.
warning
#b58900
WARNING: Requested 16 jobs exceeds available CPU cores (8).
debug
#586e75
DEBUG: Resolved /etc/myapp/config.toml.
option
#268bd2 bold
--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand
#268bd2 bold
Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice
#6c71c4 bold
--format [json|csv|xml]   Output format. Defaults to json.
metavar
#268bd2 dim italic
--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket
#586e75
--port INTEGER    [env var: PORT; default: 8080; required]
envvar
#cb4b16 dim
--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default
#859900 dim italic
--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label
#268bd2 dim
--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required
#dc322f dim
--token TEXT    Authentication token.  [required]
argument
#268bd2 italic
Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated
#d33682
--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search
#b58900
--retry-budget INTEGER    The retry budget.
success
#859900
 database migration completed
 1,245 records imported
subheading
#2aa198
◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8

Module exports

click_extra.theme exposes two themes and a pair of accessor helpers:

  • nocolor_theme: an all-identity theme used when ANSI rendering is suppressed.

  • get_default_theme() / set_default_theme(theme): read or override the process-wide fallback. The default is the built-in dark palette. ThemeOption does not call set_default_theme: per-invocation choices live on ctx.meta instead. click_extra.cli_wrapper.patch_click() calls set_default_theme() to override the fallback for the entire patched session.

Use click_extra.theme.get_current_theme() to read the theme that applies to the current invocation: it consults the active Click context first and falls back to get_default_theme().

Adding a new built-in theme

A built-in theme is a single TOML table in click_extra/themes.toml: declare a [<name>] table with one inline-table per styled slot. The file is parsed at import time via HelpTheme.from_dict, so adding a theme requires no Python: only the data:

# click_extra/themes.toml

[zenburn]
# Zenburn by Jani Nurminen.
# Palette: https://kippura.org/zenburnpage/
invoked_command = { fg = "#dcdccc", bold = true }
heading = { fg = "#8cd0d3", bold = true, underline = true }
option = { fg = "#8cd0d3" }
# ... fill in the rest of the slots

Tables are kept in alphabetical order; tests/test_theme.py enforces this. The slot mapping is the work: generic color-scheme catalogs (base16, pygments, iTerm palettes) don’t expose the semantic roles Click Extra needs (option, metavar, choice, deprecated, envvar, …), so each theme is hand-curated. Use the existing solarized_dark, dracula, nord, and monokai tables as templates.

Registering a custom theme

The list of valid --theme choices is pulled from click_extra.theme.theme_registry (plus per-invocation overrides from --config) at parse time. To add your own theme from a downstream package, call register_theme() before declaring your commands:

from click_extra import (
    BUILTIN_THEMES,
    Color,
    Style,
    command,
    echo,
    register_theme,
)

NEON = BUILTIN_THEMES["dark"].with_(
    heading=Style(fg=Color.bright_magenta, bold=True, underline=True),
    option=Style(fg=Color.bright_cyan),
    choice=Style(fg=Color.bright_yellow),
)
register_theme("neon", NEON)


@command
def cocktail():
    """Mix a cocktail."""
    echo("Cheers!")

After this runs, cocktail --theme neon becomes a valid invocation, and cocktail --help lists neon alongside the built-in choices.

Tip

For themes that depend on runtime state (terminal-background detection, environment variables, user settings), compute the HelpTheme once at startup and pass it to register_theme. The registry holds plain instances only: if you need lazy or per-invocation resolution, load the theme from [tool.<cli>.themes.<name>] (see Themes from your --config file below) so it lands on ctx.meta rather than the process-wide dict.

Anatomy of a theme

HelpTheme is a frozen dataclass that extends cloup.HelpTheme with extra styling slots for log levels and Click Extra’s own categories.

Use with_() to derive a new theme that only overrides a few styles:

from click_extra import BUILTIN_THEMES, Style, Color

minimal = BUILTIN_THEMES["dark"].with_(
    option=Style(fg=Color.white),
    choice=Style(fg=Color.white, dim=True),
)

with_() returns the same instance when no styles change and validates that all keyword arguments match a known field, so typos like optoin=... raise immediately.

Literal and replaceable slots

The styling slots carry a second, coarser classification borrowed from man-pages(7): literal tokens the user types verbatim versus replaceable tokens the user substitutes with a real value. Man pages render the former in bold and the latter in italic, “even in the SYNOPSIS section”. click_extra.theme records that mapping as two frozensets of slot names:

  • LITERAL_STYLES: invoked_command, subcommand, alias, alias_secondary, option, choice.

  • REPLACEABLE_STYLES: metavar, argument.

Every remaining slot (log levels, the [default: ...] and [env var: ...] bracket fields, headings, …) sits outside the dichotomy. Every built-in theme applies this split: literal slots render bold and replaceable slots italic, even inside the color palettes, and the manpage theme renders it with nothing else. A future man-page generator can reuse the same two sets to map each styled token to roff’s \fB / \fI.

Cross-reference highlighting

The cross_ref_highlight flag (default True) controls whether option names, choices, arguments, metavars, and CLI names are highlighted wherever they appear in free-form prose. Disable it for a calmer help screen:

calm = BUILTIN_THEMES["dark"].with_(cross_ref_highlight=False)

See Cross-reference highlighting for the details on what stays styled when the flag is off.

Manual loading from a mapping

HelpTheme.to_dict() and HelpTheme.from_dict() round-trip a theme through plain mappings, so a theme can live in a TOML, JSON, or YAML file alongside the rest of an application’s configuration:

[my_theme]
option = { fg = "cyan" }
heading = { fg = "bright_blue", bold = true, underline = true }
choice = { fg = "magenta" }
import tomllib
from pathlib import Path

from click_extra import HelpTheme, register_theme

raw = tomllib.loads(Path("config.toml").read_text())
register_theme("my_theme", HelpTheme.from_dict(raw["my_theme"]))

to_dict() only emits slots that diverge from the default (identity / None), and from_dict() raises TypeError on unknown keys, so configuration typos surface at load time rather than silently producing a half-styled theme.

For the much more common case where the theme should live in the same --config file the CLI already reads, see the next section: click-extra wires the loader for you.

Themes from your config file

ConfigOption recognizes a themes sub-table inside the app’s section. Every [<cli>.themes.<name>] entry is parsed via HelpTheme.from_dict and made available to --theme for the duration of the invocation, with two distinct behaviors depending on whether <name> matches a built-in:

  • Override an existing palette. Re-declare a built-in name (dark, dracula, light, …) and the slots you set are overlaid on top of the built-in palette via HelpTheme.cascade. Unset slots inherit from the built-in, so a one-line override like option = { fg = "bright_cyan" } is enough.

  • Define a new palette. Use any other name and --theme <name> becomes a valid choice for that invocation. Unset slots default to no styling (identity), so you typically declare a slot for every category you care about.

In both cases the theme registry mutation is per-invocation: it lives on ctx.meta under click_extra.context.THEME_OVERRIDES and never touches the module-level theme_registry. Sphinx builds, test runners, and any other host process running multiple CLI invocations back-to-back never leak themes between them.

Override an existing built-in

from click_extra import command, echo

@command
def weather():
    """Show the local weather forecast."""
    echo("Sunny, 22°C.")

Drop the override under [<cli>.themes.dark] in your weather.toml:

[weather.themes.dark]
option = { fg = "bright_cyan" }
choice = { fg = "yellow", bold = true }

Then ask for --help with the override applied (the rest of the dark palette stays put):

$ weather --config /tmp/tmp8d3d6tsq/weather.toml --help
Load configuration matching /tmp/tmp8d3d6tsq/weather.toml
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               dark]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

Define a brand-new theme

[weather.themes.midnight]
option = { fg = "blue", bold = true }
heading = { fg = "magenta" }
choice = { fg = "yellow" }
default = { fg = "green", italic = true }

The new name immediately shows up in --help’s --theme metavar and is selectable on the command line:

$ weather --config /tmp/tmp0tagc33r/weather.toml --help
Load configuration matching /tmp/tmp0tagc33r/weather.toml
Usage: weather [OPTIONS]

  Show the local weather forecast.

Options:
  --time / --no-time           Measure and print elapsed execution time.
                               [default: no-time]
  --config CONFIG_PATH         Location of the configuration file. Supports
                               local path with glob patterns or remote URL.
                               [default: ~/.config/weather/{*.toml,*.yaml,*.yml,
                               *.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproj
                               ect.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.
  --export-config FORMAT       Export the configuration in the selected format
                               to <stdout>, then exit.
  --accessible                 Accessibility mode: disable colors and render
                               tables in a plain, screen-reader-friendly format.
  --color [auto|always|never]  Colorize the output. A bare --color is the same
                               as --color=always.  [default: auto]
  --no-color                   Disable colorization (alias of --color=never).
  --progress / --no-progress   Show progress indicators during long operations.
                               Disabled for non-interactive output (pipes, dumb
                               terminals, CI) and by --accessible.  [default:
                               progress]
  --theme [dark|dracula|light|manpage|midnight|monokai|nord|solarized_dark]
                               Color theme used for help screens.  [default:
                               midnight]
  --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]
  -q, --quiet                  Decrease the default WARNING verbosity by one
                               level for each additional repetition of the
                               option.  [default: 0]
  --man                        Show the command's man page (roff) and exit.
  --version                    Show the version and exit.
  -h, --help                   Show this message and exit.

The same [weather] theme = "midnight" selector you’d use for a built-in works here: pre-pick the new theme as the default for invocations of this CLI.

Validation

Malformed entries surface as ValidationError with a path rooted at the configuration file root, both during --validate-config and at normal load time:

[weather.themes.midnight]
optoin = { fg = "blue" } # typo
$ weather --validate-config /tmp/tmpnw26raxx/weather.toml
Configuration validation error: weather.themes.midnight: Unknown HelpTheme field(s): optoin

The built-in ConfigValidator for the themes sub-tree is auto-registered on every ConfigOption, so app authors don’t have to opt in. Apps that ship their own ConfigValidator continue to work alongside it.

Interaction with --color / --no-color

--theme controls which colors are used. --color / --no-color controls whether colors are emitted at all. The two are independent:

  • --theme light with --no-color emits no ANSI codes.

  • --theme dark with --color (the default) emits the dark theme’s ANSI codes.

  • NO_COLOR=1 in the environment overrides any --theme choice by silencing all ANSI output.

The --color callback inspects the standard set of color environment variables (NO_COLOR, CLICOLOR, FORCE_COLOR, LLM, etc.) before the theme is applied: see color_envvars for the full list.

click_extra.theme API

        classDiagram
  ExtraOption <|-- ThemeOption
  HelpTheme <|-- HelpTheme
  ParamType <|-- ThemeChoice
    

Help-screen color themes for Click Extra.

Holds the HelpTheme dataclass (pure data, no factory methods), the nocolor_theme constant, the process-wide fallback accessed via get_default_theme() / set_default_theme(), the named-theme theme_registry plus register_theme() helper, and the ThemeOption that exposes --theme on every Click Extra command.

The built-in themes (dark, dracula, light, manpage, monokai, nord, solarized_dark) live in the package data file click_extra/themes.toml and are loaded at module import time via HelpTheme.from_dict(). manpage is a colorless theme that shadows man-pages(7) typography (bold literals, italic replaceable); the others apply that same bold/italic split on top of their color palettes. Adding a new built-in theme is a one-file edit in that TOML file: no Python needed. The same TOML schema is used for user-defined themes loaded from configuration: see Themes for the user guide.

Note

The active theme for a CLI invocation is stored on the Click context’s meta dict under click_extra.context.THEME by ThemeOption. Use get_current_theme() to retrieve it: that helper consults the active Click context first and falls back to get_default_theme() when no context is in flight (like at import time, in wrap patching, or in bare REPL usage). Per-invocation context storage means concurrent invocations of the same CLI in one process (Sphinx builds, test runners, REPLs) do not leak --theme choices into each other.

class click_extra.theme.HelpTheme(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 slots for log levels and the structural elements Click Extra highlights in help screens.

Each slot below documents what it colors. The built-in themes shipped in BUILTIN_THEMES provide the visual styling by setting the relevant slots; user-defined themes can be authored as plain mappings and loaded via from_dict().

critical()

Style applied to the CRITICAL level name in log records.

Example: CRITICAL: Database connection lost.

Return type:

TypeVar(T)

Rendered with the default dark theme:

CRITICAL: Database connection lost.
error()

Style applied to the ERROR level name in log records.

Example: ERROR: Configuration file not found.

Return type:

TypeVar(T)

Rendered with the default dark theme:

ERROR: Configuration file not found.
warning()

Style applied to the WARNING level name in log records.

Example: WARNING: Requested 16 jobs exceeds available CPU cores (8).

Return type:

TypeVar(T)

Rendered with the default dark theme:

WARNING: Requested 16 jobs exceeds available CPU cores (8).
info()

Style applied to the INFO level name in log records.

Usually left at identity: INFO is the default verbosity and shouldn’t stand out from regular output.

Return type:

TypeVar(T)

Rendered with the default dark theme:

INFO: Loaded 23 records.
debug()

Style applied to the DEBUG level name in log records.

Example: DEBUG: Resolved /etc/myapp/config.toml.

Return type:

TypeVar(T)

Rendered with the default dark theme:

DEBUG: Resolved /etc/myapp/config.toml.
option()

Style applied to option names (--config, -v, --color/--no-color) wherever they appear: synopsis column, free-form descriptions, and docstrings (when cross_ref_highlight is enabled).

Return type:

TypeVar(T)

Rendered with the default dark theme:

--config CONFIG_PATH    Location of the configuration file.
-v, --verbose           Increase verbosity.
subcommand()

Style applied to subcommand names: in a group’s command list and wherever they are referenced in prose.

Return type:

TypeVar(T)

Rendered with the default dark theme:

Commands:
  backup        Snapshot the data store.
  restore       Restore from a snapshot.
choice()

Style applied to each individual value inside a click.Choice metavar (like json, csv, xml within [json|csv|xml]) and to those values referenced in option descriptions.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--format [json|csv|xml]   Output format. Defaults to json.
metavar()

Style applied to type metavars (INTEGER, TEXT, PATH, FILE, …) that follow an option name in the synopsis column.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--output TEXT       Destination file.
--workers INTEGER   Worker count.
bracket()

Style applied to the literal bracket characters and label prefixes of trailing fields: [, ], default:, env var:, and the field separators between them. Also acts as the fallback for the four inner bracket-field slots (envvar, default, required, range_label) whenever any of them is left at identity. A theme that only sets bracket therefore renders the whole bracket field with a single uniform style; richer themes layer specific colors on top by setting the inner slots.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--port INTEGER    [env var: PORT; default: 8080; required]
envvar()

Style applied to environment-variable values inside [env var: ...] bracket fields, and to envvar names mentioned in option descriptions. Falls back to bracket when left at identity, so a theme that only styles bracket still gets a consistent rendering inside bracket fields.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--threshold INTEGER   Acceptable error rate.
                      [env var: THRESHOLD, TEST_THRESHOLD]
default()

Style applied to the default-value content inside [default: ...] bracket fields. Falls back to bracket when left at identity.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--output FILENAME    Destination file.  [default: out.csv]
--retries INTEGER    Retry budget.  [default: 5]
range_label()

Style applied to range expressions (0<=x<=9, x>=1024, 0<=x<100) that appear inside bracket fields for IntRange and FloatRange options. Falls back to bracket when left at identity.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--level INTEGER RANGE    Verbosity level.  [0<=x<=9]
--port INTEGER RANGE     Bind port.        [x>=1024]
required()

Style applied to the required label inside bracket fields on mandatory options. Falls back to bracket when left at identity.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--token TEXT    Authentication token.  [required]
argument()

Style applied to argument metavars (positional parameter names like MY_ARG, SCRIPT, [FILENAMES]...) in the synopsis column and when referenced in prose.

Return type:

TypeVar(T)

Rendered with the default dark theme:

Usage: cp [OPTIONS] SRC DST
Usage: pack [OPTIONS] [FILES]... [OUTPUT]
deprecated()

Style applied to (DEPRECATED) / (Deprecated: reason) markers appended to options and commands.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--old-api    Legacy endpoint. (DEPRECATED: use --new-api instead)
--legacy     Kept for compatibility. (deprecated: removed in v9)
search()

Style applied to substring matches in <cli> help --search output, so users can spot where their query matched.

Return type:

TypeVar(T)

Rendered with the default dark theme:

--retry-budget INTEGER    The retry budget.
success()

Style applied to success glyphs in pre-rendered UI elements (the in OK_GLYPH) and any text passed through this slot by downstream code.

Return type:

TypeVar(T)

Rendered with the default dark theme:

 database migration completed
 1,245 records imported
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()

Style for sub-section headings inside log output or inline help.

Distinct from heading (which styles the top-level help-screen section titles): subheading is intended for downstream code that wants a second styling level for its own narrative output.

See also

Used by mail-deduplicate to style N mails sharing hash log lines.

Return type:

TypeVar(T)

Rendered with the default dark theme:

◼ 3 mails sharing hash a1b2c3d4
◼ 7 mails sharing hash e5f6a7b8
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:

HelpTheme

to_dict()[source]

Serialize the theme to a plain dict suitable for TOML/JSON/YAML.

Each Style slot is emitted via Style.to_dict. Slots left at their default (identity or None) are omitted, so the output only carries what the theme actually overrides. Pair with from_dict() to round-trip.

Raises:

TypeError – when a slot holds an opaque IStyle callable that is not a Style (those cannot be serialized).

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Build a theme from the plain dict produced by to_dict().

Each value is interpreted by field type: a mapping becomes a Style via Style.from_dict, while cross_ref_highlight is read as a plain bool. Unknown keys raise TypeError so typos surface immediately.

Return type:

HelpTheme

cascade(base)[source]

Layer this theme’s set slots on top of base.

Mirrors Style.cascade at the slot level: this theme’s non-default slots win, base fills the rest. Useful for layering a sparse override (typically parsed from a config file’s [tool.<cli>.themes.<name>] table) on top of a full built-in palette.

Raises:

TypeError – when base is not a HelpTheme.

Return type:

HelpTheme

click_extra.theme.LITERAL_STYLES: frozenset[str] = frozenset({'alias', 'alias_secondary', 'choice', 'invoked_command', 'option', 'subcommand'})

Names of the HelpTheme slots that color literal tokens: text the user types verbatim on the command line.

Covers the command and subcommand names, their aliases, option flags (--config, -v), and the concrete values of a click.Choice (json in [json|csv|xml]).

These map to the bold font of the man-pages(7) typographic convention, which sets text “typed literally” in bold (\fB in roff) “even in the SYNOPSIS section”. Paired with REPLACEABLE_STYLES: the two are disjoint, and every remaining slot is an annotation, prose, or chrome style that the literal/replaceable dichotomy does not classify (log levels, [default: ...] / [env var: ...] fields, headings, …).

Note

Every built-in theme applies this classification: literal slots render bold and REPLACEABLE_STYLES italic, mirroring a man page even in the color palettes. tests/test_theme.py enforces the invariant, and the manpage built-in theme is its pure-monochrome embodiment (bold/italic, no color). A man-page generator can reuse the same two sets to map each styled token to \fB / \fI. See Benchmark for the man-page generation gap.

click_extra.theme.REPLACEABLE_STYLES: frozenset[str] = frozenset({'argument', 'metavar'})

Names of the HelpTheme slots that color replaceable tokens: placeholders the user substitutes with a real value.

Covers type metavars on options (INTEGER, CONFIG_PATH) and positional argument metavars (SOURCE, [FILENAMES]...).

These map to the italic font of the man-pages(7) convention, which sets replaceable arguments in italic (\fI in roff). See LITERAL_STYLES for the bold counterpart and the full rationale.

click_extra.theme.nocolor_theme: HelpTheme = HelpTheme(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.

All style slots default to identity, so styling calls return the raw text unchanged.

click_extra.theme.get_default_theme()[source]

Return the process-wide fallback theme.

Read by get_current_theme() when no Click context is active or when the active context has no theme set. The default is the built-in dark palette; patch_click() overrides it via set_default_theme() for the duration of a patched session.

Resolved through a function rather than a module attribute so callers always observe the current value: capturing default_theme as a default function parameter (the previous pattern) would freeze whatever was set at import time.

Return type:

HelpTheme

click_extra.theme.set_default_theme(theme)[source]

Override the process-wide fallback theme.

ThemeOption writes its picked theme to ctx.meta rather than calling this helper, so per-invocation choices do not leak across invocations sharing the same process. Use this only for genuinely process-wide overrides: patch_click() is the canonical caller.

Return type:

None

click_extra.theme.get_current_theme()[source]

Return the theme active for the current CLI invocation.

Resolution order:

  1. The theme stored on the active Click context under click_extra.context.THEME (set by ThemeOption from --theme).

  2. The process-wide fallback returned by get_default_theme() (the dark default, or whatever patch_click() set at process start).

Falling back through the active context (instead of reading a module attribute) keeps --theme scoped to the invocation that received it, so a second invocation in the same process starts from the default again.

Return type:

HelpTheme

click_extra.theme.theme_registry: dict[str, HelpTheme] = {'dark': HelpTheme(invoked_command=Style(fg='bright_white', bold), command_help=<function identity>, heading=Style(fg='bright_blue', underline), constraint=Style(fg='magenta'), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg='cyan', bold), alias_secondary=Style(fg='cyan', bold, dim), epilog=<function identity>, critical=Style(fg='red', bold), error=Style(fg='red'), warning=Style(fg='yellow'), info=<function identity>, debug=Style(fg='blue'), option=Style(fg='cyan', bold), subcommand=Style(fg='cyan', bold), choice=Style(fg='magenta', bold), metavar=Style(fg='cyan', dim, italic), bracket=Style(dim), envvar=Style(fg='yellow', dim), default=Style(fg='green', dim, italic), range_label=Style(fg='cyan', dim), required=Style(fg='red', dim), argument=Style(fg='cyan', italic), deprecated=Style(fg='bright_yellow'), search=Style(fg='green'), success=Style(fg='green'), cross_ref_highlight=True, subheading=Style(fg='blue')), 'dracula': HelpTheme(invoked_command=Style(fg=#f8f8f2, bold), command_help=<function identity>, heading=Style(fg=#ff79c6, underline), constraint=Style(fg=#ff79c6), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#8be9fd, bold), alias_secondary=Style(fg=#8be9fd, bold, dim), epilog=<function identity>, critical=Style(fg=#ff5555, bold), error=Style(fg=#ff5555), warning=Style(fg=#ffb86c), info=<function identity>, debug=Style(fg=#6272a4), option=Style(fg=#bd93f9, bold), subcommand=Style(fg=#bd93f9, bold), choice=Style(fg=#ff79c6, bold), metavar=Style(fg=#bd93f9, dim, italic), bracket=Style(fg=#6272a4), envvar=Style(fg=#ffb86c, dim), default=Style(fg=#50fa7b, dim, italic), range_label=Style(fg=#bd93f9, dim), required=Style(fg=#ff5555, dim), argument=Style(fg=#bd93f9, italic), deprecated=Style(fg=#ffb86c), search=Style(fg=#f1fa8c), success=Style(fg=#50fa7b), cross_ref_highlight=True, subheading=Style(fg=#8be9fd)), 'light': HelpTheme(invoked_command=Style(fg='black', bold), command_help=<function identity>, heading=Style(fg='magenta', underline), constraint=Style(fg='magenta'), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg='blue', bold), alias_secondary=Style(fg='blue', bold, dim), epilog=<function identity>, critical=Style(fg='red', bold), error=Style(fg='red'), warning=Style(fg='magenta'), info=<function identity>, debug=Style(fg='blue', dim), option=Style(fg='blue', bold), subcommand=Style(fg='blue', bold), choice=Style(fg='magenta', bold), metavar=Style(fg='blue', dim, italic), bracket=Style(dim), envvar=Style(fg='magenta', dim), default=Style(fg='green', dim, italic), range_label=Style(fg='blue', dim), required=Style(fg='red', dim), argument=Style(fg='blue', italic), deprecated=Style(fg='red'), search=Style(fg='green'), success=Style(fg='green'), cross_ref_highlight=True, subheading=Style(fg='blue', dim)), 'manpage': HelpTheme(invoked_command=Style(bold), command_help=<function identity>, heading=Style(underline), constraint=<function identity>, section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(bold), alias_secondary=Style(bold), epilog=<function identity>, critical=<function identity>, error=<function identity>, warning=<function identity>, info=<function identity>, debug=<function identity>, option=Style(bold), subcommand=Style(bold), choice=Style(bold), metavar=Style(italic), bracket=<function identity>, envvar=<function identity>, default=<function identity>, range_label=<function identity>, required=<function identity>, argument=Style(italic), deprecated=<function identity>, search=<function identity>, success=<function identity>, cross_ref_highlight=True, subheading=<function identity>), 'monokai': HelpTheme(invoked_command=Style(fg=#f8f8f2, bold), command_help=<function identity>, heading=Style(fg=#a6e22e, underline), constraint=Style(fg=#ae81ff), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#a6e22e, bold), alias_secondary=Style(fg=#a6e22e, bold, dim), epilog=<function identity>, critical=Style(fg=#f92672, bold), error=Style(fg=#f92672), warning=Style(fg=#fd971f), info=<function identity>, debug=Style(fg=#75715e), option=Style(fg=#66d9ef, bold), subcommand=Style(fg=#66d9ef, bold), choice=Style(fg=#ae81ff, bold), metavar=Style(fg=#66d9ef, dim, italic), bracket=Style(fg=#75715e), envvar=Style(fg=#fd971f, dim), default=Style(fg=#e6db74, dim, italic), range_label=Style(fg=#66d9ef, dim), required=Style(fg=#f92672, dim), argument=Style(fg=#66d9ef, italic), deprecated=Style(fg=#fd971f), search=Style(fg=#e6db74), success=Style(fg=#a6e22e), cross_ref_highlight=True, subheading=Style(fg=#a6e22e)), 'nord': HelpTheme(invoked_command=Style(fg=#eceff4, bold), command_help=<function identity>, heading=Style(fg=#5e81ac, underline), constraint=Style(fg=#b48ead), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#8fbcbb, bold), alias_secondary=Style(fg=#8fbcbb, bold, dim), epilog=<function identity>, critical=Style(fg=#bf616a, bold), error=Style(fg=#bf616a), warning=Style(fg=#d08770), info=<function identity>, debug=Style(fg=#4c566a), option=Style(fg=#81a1c1, bold), subcommand=Style(fg=#81a1c1, bold), choice=Style(fg=#b48ead, bold), metavar=Style(fg=#81a1c1, dim, italic), bracket=Style(fg=#4c566a), envvar=Style(fg=#d08770, dim), default=Style(fg=#a3be8c, dim, italic), range_label=Style(fg=#81a1c1, dim), required=Style(fg=#bf616a, dim), argument=Style(fg=#81a1c1, italic), deprecated=Style(fg=#d08770), search=Style(fg=#ebcb8b), success=Style(fg=#a3be8c), cross_ref_highlight=True, subheading=Style(fg=#88c0d0)), 'solarized_dark': HelpTheme(invoked_command=Style(fg=#eee8d5, bold), command_help=<function identity>, heading=Style(fg=#6c71c4, underline), constraint=Style(fg=#6c71c4), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#2aa198, bold), alias_secondary=Style(fg=#2aa198, bold, dim), epilog=<function identity>, critical=Style(fg=#dc322f, bold), error=Style(fg=#dc322f), warning=Style(fg=#b58900), info=<function identity>, debug=Style(fg=#586e75), option=Style(fg=#268bd2, bold), subcommand=Style(fg=#268bd2, bold), choice=Style(fg=#6c71c4, bold), metavar=Style(fg=#268bd2, dim, italic), bracket=Style(fg=#586e75), envvar=Style(fg=#cb4b16, dim), default=Style(fg=#859900, dim, italic), range_label=Style(fg=#268bd2, dim), required=Style(fg=#dc322f, dim), argument=Style(fg=#268bd2, italic), deprecated=Style(fg=#d33682), search=Style(fg=#b58900), success=Style(fg=#859900), cross_ref_highlight=True, subheading=Style(fg=#2aa198))}

Process-wide registry of named themes used by ThemeOption.

Each entry maps a theme name to its HelpTheme instance. Built-in themes are seeded here at module load time from BUILTIN_THEMES (loaded from click_extra/themes.toml).

Use register_theme() to add your own at import time, or declare them in your CLI’s config file under [tool.<cli>.themes.<name>]: the latter goes through ConfigOption, lands on ctx.meta (see click_extra.context.THEME_OVERRIDES), and never mutates this module-level dict, so per-invocation choices don’t leak between sibling invocations sharing the same process.

click_extra.theme.register_theme(name, theme)[source]

Register a named theme in the module-level theme_registry.

Parameters:
  • name (str) – Lowercase identifier used as the --theme choice value.

  • theme (HelpTheme) – A HelpTheme instance.

Return type:

None

click_extra.theme.get_theme_registry(ctx=None)[source]

Return the theme registry visible to ctx.

Merges the module-level theme_registry with any per-invocation overrides stored on ctx.meta under click_extra.context.THEME_OVERRIDES. Per-invocation entries win on key collisions, which is what lets a config file’s [tool.<cli>.themes.dark] table override the built-in dark palette for one invocation without touching the global registry.

When ctx is None or has no overrides, returns a copy of the module-level registry.

Return type:

dict[str, HelpTheme]

click_extra.theme.AUTO_THEME: str = 'auto'

Reserved --theme value resolving the palette from the terminal background.

Unlike the named built-in palettes, auto is not a registry entry: it is a directive handled by ThemeOption, which calls resolve_auto_theme() to pick dark or light from the detected background, mirroring --color=auto. Kept out of the --help metavar and shell completion (which only advertise registered palettes), so a CLI that does not opt into auto detection keeps an unchanged help screen, yet accepted by ThemeChoice.convert() so --theme=auto works on every Click Extra CLI.

click_extra.theme.resolve_auto_theme(ctx=None, query_background=False)[source]

Pick a built-in palette from the detected terminal background.

Resolves the background mode via resolve_background() and maps "dark" / "light" to the same-named theme in the registry visible to ctx (built-ins plus any [tool.<cli>.themes.<name>] config overlays). An undetected background falls back to "dark", preserving Click Extra’s default.

Parameters:
  • ctx (Context | None) – context whose theme registry is consulted.

  • query_background (bool) – when true, allow the live OSC 11 terminal query (query_osc_background()) on top of the environment-variable signals. Off by default because the query reads stdin.

Return type:

HelpTheme | None

Returns:

the chosen HelpTheme, or None when neither the detected palette nor the dark fallback is registered (the themes.toml data file was dropped). A None leaves ctx.meta untouched so get_current_theme() keeps the no-color default.

click_extra.theme.themes_from_config(table)[source]

Build a {name: HelpTheme} mapping from a [tool.<cli>.themes] sub-tree.

For each entry, build a HelpTheme via HelpTheme.from_dict(). If name matches an existing key in theme_registry, the new theme is layered on top via HelpTheme.cascade() so partial overrides (like just one slot) inherit the rest from the built-in palette. Stand-alone names produce theme instances with the unset slots left at their defaults.

Return type:

dict[str, HelpTheme]

click_extra.theme.validate_themes_config(themes_subtree)[source]

Validate a [tool.<cli>.themes] sub-tree.

Registered as a built-in ConfigValidator by ConfigOption so malformed theme tables surface as ValidationError with a rooted path (my-cli.themes.<name>) rather than a deep TypeError from HelpTheme.from_dict().

Return type:

None

class click_extra.theme.ThemeChoice(case_sensitive=False)[source]

Bases: ParamType

A click.ParamType whose choices track the live theme registry.

Implements the click.Choice-shaped duck interface (choices, case_sensitive, normalize_choice) so click_extra.highlight can collect theme names for per-token highlighting through the same code path it uses for Click’s own Choice. The choices attribute is a property that queries get_theme_registry() at every lookup, so themes registered late (typically by ConfigOption parsing [tool.<cli>.themes.<name>] tables before --theme is processed) are valid choices and appear in the --help metavar.

Implemented as a fresh click.ParamType rather than a click.Choice subclass to avoid relying on Click’s setter semantics for self.choices: the previous subclass design swallowed Click’s __init__-time assignment with a no-op setter, which would silently break under any future Click version that uses object.__setattr__ (like for slots) instead of regular attribute assignment.

name: str = 'choice'

the descriptive name of this type

property choices: tuple[str, ...]

Theme names visible in the current context, alphabetically sorted.

normalize_choice(choice, ctx)[source]

Mirrors click.Choice.normalize_choice() for highlight compatibility.

Return type:

str

get_metavar(param, ctx)[source]

Returns the metavar default for this param if it provides one.

Return type:

str | None

convert(value, param, ctx)[source]

Resolve value to a canonical theme name from the live registry.

Normalizes value and looks it up against the names visible in ctx. Returns the canonical name, None when no themes are registered at all (an inert --theme), and calls fail when value is not a string or does not match any registered theme.

Return type:

str | None

shell_complete(ctx, param, incomplete)[source]

Return a list of CompletionItem objects for the incomplete value. Most types do not provide completions, but some do, and this allows custom types to provide custom completions as well.

Parameters:
  • ctx (Context) – Invocation context for this command.

  • param (Parameter) – The parameter that is requesting completion.

  • incomplete (str) – Value being completed. May be empty.

Added in version 8.0.

Return type:

list[CompletionItem]

class click_extra.theme.ThemeOption(param_decls=None, default='dark', is_eager=True, expose_value=False, query_background=False, help='Color theme used for help screens.', **kwargs)[source]

Bases: ExtraOption

A pre-configured option that adds --theme to select the help-screen palette.

Accepts any name registered in theme_registry or in the per-invocation overrides loaded by ConfigOption from [tool.<cli>.themes.<name>]. Validation goes through ThemeChoice, which reads the live registry at parse time, so config-defined themes appear as valid choices and in the --help metavar without any further wiring.

The resolved HelpTheme lands on the Click context under click_extra.context.THEME and applies for the duration of the current invocation only.

The reserved value AUTO_THEME (--theme=auto) is also accepted on every CLI: it resolves the palette from the terminal background via resolve_auto_theme() instead of naming a registered theme. Background detection reads environment variables by default; pass query_background=True to additionally allow the live OSC 11 terminal query (query_osc_background()), which is opt-in because it reads stdin.

set_theme(ctx, param, value)[source]

Resolve the chosen theme name and store it on the Click context.

ThemeChoice has already validated value against the live registry (or accepted the AUTO_THEME directive) by the time this fires. A plain palette name is looked up unconditionally; auto is resolved from the terminal background via resolve_auto_theme(), leaving ctx.meta untouched when no palette can be resolved so get_current_theme() keeps its default.

Return type:

None

click_extra.theme.BUILTIN_THEMES: dict[str, HelpTheme] = {'dark': HelpTheme(invoked_command=Style(fg='bright_white', bold), command_help=<function identity>, heading=Style(fg='bright_blue', underline), constraint=Style(fg='magenta'), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg='cyan', bold), alias_secondary=Style(fg='cyan', bold, dim), epilog=<function identity>, critical=Style(fg='red', bold), error=Style(fg='red'), warning=Style(fg='yellow'), info=<function identity>, debug=Style(fg='blue'), option=Style(fg='cyan', bold), subcommand=Style(fg='cyan', bold), choice=Style(fg='magenta', bold), metavar=Style(fg='cyan', dim, italic), bracket=Style(dim), envvar=Style(fg='yellow', dim), default=Style(fg='green', dim, italic), range_label=Style(fg='cyan', dim), required=Style(fg='red', dim), argument=Style(fg='cyan', italic), deprecated=Style(fg='bright_yellow'), search=Style(fg='green'), success=Style(fg='green'), cross_ref_highlight=True, subheading=Style(fg='blue')), 'dracula': HelpTheme(invoked_command=Style(fg=#f8f8f2, bold), command_help=<function identity>, heading=Style(fg=#ff79c6, underline), constraint=Style(fg=#ff79c6), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#8be9fd, bold), alias_secondary=Style(fg=#8be9fd, bold, dim), epilog=<function identity>, critical=Style(fg=#ff5555, bold), error=Style(fg=#ff5555), warning=Style(fg=#ffb86c), info=<function identity>, debug=Style(fg=#6272a4), option=Style(fg=#bd93f9, bold), subcommand=Style(fg=#bd93f9, bold), choice=Style(fg=#ff79c6, bold), metavar=Style(fg=#bd93f9, dim, italic), bracket=Style(fg=#6272a4), envvar=Style(fg=#ffb86c, dim), default=Style(fg=#50fa7b, dim, italic), range_label=Style(fg=#bd93f9, dim), required=Style(fg=#ff5555, dim), argument=Style(fg=#bd93f9, italic), deprecated=Style(fg=#ffb86c), search=Style(fg=#f1fa8c), success=Style(fg=#50fa7b), cross_ref_highlight=True, subheading=Style(fg=#8be9fd)), 'light': HelpTheme(invoked_command=Style(fg='black', bold), command_help=<function identity>, heading=Style(fg='magenta', underline), constraint=Style(fg='magenta'), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg='blue', bold), alias_secondary=Style(fg='blue', bold, dim), epilog=<function identity>, critical=Style(fg='red', bold), error=Style(fg='red'), warning=Style(fg='magenta'), info=<function identity>, debug=Style(fg='blue', dim), option=Style(fg='blue', bold), subcommand=Style(fg='blue', bold), choice=Style(fg='magenta', bold), metavar=Style(fg='blue', dim, italic), bracket=Style(dim), envvar=Style(fg='magenta', dim), default=Style(fg='green', dim, italic), range_label=Style(fg='blue', dim), required=Style(fg='red', dim), argument=Style(fg='blue', italic), deprecated=Style(fg='red'), search=Style(fg='green'), success=Style(fg='green'), cross_ref_highlight=True, subheading=Style(fg='blue', dim)), 'manpage': HelpTheme(invoked_command=Style(bold), command_help=<function identity>, heading=Style(underline), constraint=<function identity>, section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(bold), alias_secondary=Style(bold), epilog=<function identity>, critical=<function identity>, error=<function identity>, warning=<function identity>, info=<function identity>, debug=<function identity>, option=Style(bold), subcommand=Style(bold), choice=Style(bold), metavar=Style(italic), bracket=<function identity>, envvar=<function identity>, default=<function identity>, range_label=<function identity>, required=<function identity>, argument=Style(italic), deprecated=<function identity>, search=<function identity>, success=<function identity>, cross_ref_highlight=True, subheading=<function identity>), 'monokai': HelpTheme(invoked_command=Style(fg=#f8f8f2, bold), command_help=<function identity>, heading=Style(fg=#a6e22e, underline), constraint=Style(fg=#ae81ff), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#a6e22e, bold), alias_secondary=Style(fg=#a6e22e, bold, dim), epilog=<function identity>, critical=Style(fg=#f92672, bold), error=Style(fg=#f92672), warning=Style(fg=#fd971f), info=<function identity>, debug=Style(fg=#75715e), option=Style(fg=#66d9ef, bold), subcommand=Style(fg=#66d9ef, bold), choice=Style(fg=#ae81ff, bold), metavar=Style(fg=#66d9ef, dim, italic), bracket=Style(fg=#75715e), envvar=Style(fg=#fd971f, dim), default=Style(fg=#e6db74, dim, italic), range_label=Style(fg=#66d9ef, dim), required=Style(fg=#f92672, dim), argument=Style(fg=#66d9ef, italic), deprecated=Style(fg=#fd971f), search=Style(fg=#e6db74), success=Style(fg=#a6e22e), cross_ref_highlight=True, subheading=Style(fg=#a6e22e)), 'nord': HelpTheme(invoked_command=Style(fg=#eceff4, bold), command_help=<function identity>, heading=Style(fg=#5e81ac, underline), constraint=Style(fg=#b48ead), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#8fbcbb, bold), alias_secondary=Style(fg=#8fbcbb, bold, dim), epilog=<function identity>, critical=Style(fg=#bf616a, bold), error=Style(fg=#bf616a), warning=Style(fg=#d08770), info=<function identity>, debug=Style(fg=#4c566a), option=Style(fg=#81a1c1, bold), subcommand=Style(fg=#81a1c1, bold), choice=Style(fg=#b48ead, bold), metavar=Style(fg=#81a1c1, dim, italic), bracket=Style(fg=#4c566a), envvar=Style(fg=#d08770, dim), default=Style(fg=#a3be8c, dim, italic), range_label=Style(fg=#81a1c1, dim), required=Style(fg=#bf616a, dim), argument=Style(fg=#81a1c1, italic), deprecated=Style(fg=#d08770), search=Style(fg=#ebcb8b), success=Style(fg=#a3be8c), cross_ref_highlight=True, subheading=Style(fg=#88c0d0)), 'solarized_dark': HelpTheme(invoked_command=Style(fg=#eee8d5, bold), command_help=<function identity>, heading=Style(fg=#6c71c4, underline), constraint=Style(fg=#6c71c4), section_help=<function identity>, col1=<function identity>, col2=<function identity>, alias=Style(fg=#2aa198, bold), alias_secondary=Style(fg=#2aa198, bold, dim), epilog=<function identity>, critical=Style(fg=#dc322f, bold), error=Style(fg=#dc322f), warning=Style(fg=#b58900), info=<function identity>, debug=Style(fg=#586e75), option=Style(fg=#268bd2, bold), subcommand=Style(fg=#268bd2, bold), choice=Style(fg=#6c71c4, bold), metavar=Style(fg=#268bd2, dim, italic), bracket=Style(fg=#586e75), envvar=Style(fg=#cb4b16, dim), default=Style(fg=#859900, dim, italic), range_label=Style(fg=#268bd2, dim), required=Style(fg=#dc322f, dim), argument=Style(fg=#268bd2, italic), deprecated=Style(fg=#d33682), search=Style(fg=#b58900), success=Style(fg=#859900), cross_ref_highlight=True, subheading=Style(fg=#2aa198))}

Mapping of built-in theme names to their HelpTheme instances.

Loaded from the package data file click_extra/themes.toml at module import time and seeded into theme_registry. Adding a new built-in theme is a one-file edit in that TOML file: declare a new [<name>] table with one inline-table per styled slot.

Index by name to access any palette, like BUILTIN_THEMES["dark"] or BUILTIN_THEMES["solarized_dark"].

Empty when the themes.toml data file is absent (some packaging and distribution setups drop it); see _load_builtin_themes for the fallback behavior.

click_extra.theme.OK_GLYPH: str = '✓'

Plain check-mark glyph for success indicators.

Style at the call site with the active theme’s success slot: get_current_theme().success(OK_GLYPH). Stored as a raw string so downstream code can render it under whichever theme is active rather than the (frozen) theme that happened to be loaded at import time.

click_extra.theme.KO_GLYPH: str = '✘'

Plain heavy-ballot-X glyph for failure indicators.

Style at the call site with the active theme’s error slot: get_current_theme().error(KO_GLYPH). See OK_GLYPH for why the glyph is exposed unstyled.

Render a theme palette as an inline-styled HTML fragment for documentation.

palette_html() is called from docs/theme.md to render every built-in theme’s palette at Sphinx build time. inject_slot_example_docstring() is registered as a Sphinx autodoc-process-docstring hook from docs/conf.py to inject a colored example into each HelpTheme slot’s autodoc block. This is build-time documentation code, kept out of the runtime theme module.

click_extra.theme_docs.inject_slot_example_docstring(app, what, name, obj, options, lines)[source]

Sphinx autodoc-process-docstring hook injecting per-slot colored examples.

For every HelpTheme slot that has an entry in _PALETTE_EXAMPLES, append an ansi-color code block to the slot’s autodoc lines. The example is rendered through _render_slot_ansi, which calls BUILTIN_THEMES["dark"].<slot>(text) to obtain the actual ANSI escapes click-extra would emit at runtime.

Wire this up from a Sphinx conf.py with:

from click_extra.theme_docs import inject_slot_example_docstring


def setup(app):
    app.connect("autodoc-process-docstring", inject_slot_example_docstring)

The hook intentionally targets only click_extra.theme.HelpTheme.<slot> names so it won’t accidentally rewrite unrelated docstrings; downstream projects can register the hook in their own conf.py if they consume HelpTheme docstrings.

Return type:

None

click_extra.theme_docs.palette_html(theme)[source]

Render a theme’s palette as an inline-styled HTML <dl> fragment.

The output is a two-column definition list (slot name → styled swatch plus attribute decorations) safe to inject into MyST or reST host documents via the python:render Sphinx directive (or any raw:: html block). Used by docs/theme.md to render every built-in theme’s palette at Sphinx build time without hand-maintaining swatch tables. Downstream projects with their own custom themes can call the same helper to get matching swatch listings in their own docs:

```{python:render}
from click_extra.theme_docs import palette_html
from my_app.themes import MY_THEME
print(palette_html(MY_THEME))
```

Slots that hold identity (no styling applied), the boolean cross_ref_highlight toggle, the internal _style_kwargs cache, and a handful of inherited cloup slots that built-ins never style are skipped: every emitted row corresponds to a real palette choice in the theme.

Return type:

str