-
-
Notifications
You must be signed in to change notification settings - Fork 898
TerminalTheme
Print the current terminal theme (foreground and background colors)
| Module type | terminaltheme |
| Default order | 32 (only used by --gen-config) |
| Module source | src/modules/terminaltheme/terminaltheme.c |
| Detection source | src/detection/terminaltheme/ |
Prints the terminal's foreground and background colours as #RRGGBB, plus whether the background
is dark.
Terminal Theme: #E5E5E5 (FG) - #000000 (BG) [Dark]
Terminal Theme: #FFFFFF (FG) - #1E1E1E (BG) [Dark]
The bracketed word at the end is the background type — the default line never prints the
foreground's. Use {fg-type} in a custom format if you need it.
| Platform | Implementation | Notes |
|---|---|---|
| All platforms | terminaltheme.c |
Escape-code query first, COLORFGBG as the fallback |
This is the only terminal-related module with no per-platform source file: terminaltheme.c sits
in the platform-independent part of the source list, and the two helpers it needs
(ffGetTerminalResponse(), getenv()) have per-platform implementations behind a common
interface. The module can still be compiled out of a build with the FF_MODULE_DISABLE_TERMINALTHEME
define, which removes both the module and the display.brightColor probe described below.
| Key | Type | Default | Description |
|---|---|---|---|
key |
string | Terminal Theme |
Module key. A single space hides the key and the separator |
keyColor |
color | – | Overrides display.color.keys
|
keyIcon |
string | built-in glyph | Printed when display.key.type includes the icon bit. Any glyph works; "" prints none. |
keyWidth |
integer | – | Overrides display.key.width
|
outputColor |
color | – | Overrides display.color.output
|
format |
string | – | Custom output format (see below) |
condition |
object | – | Show the module only if the conditions match |
There are no module-specific options. One environment variable changes the result:
| Variable | Effect |
|---|---|
COLORFGBG |
Fallback source, formatted as <fg>;<bg> with two palette indices. Only used when the escape-code query gets no answer |
Run fastfetch -h terminaltheme-format for the authoritative list.
| Variable | Description |
|---|---|
{fg-color} |
Foreground colour, #RRGGBB
|
{fg-type} |
Foreground type, Dark or Light
|
{bg-color} |
Background colour, #RRGGBB
|
{bg-type} |
Background type, Dark or Light
|
None of the four is marked * in the help output, so none is available in the key format.
Terminal Theme: #FFFFFF|Light|#7F7F7F|Dark
[
{
"type": "TerminalTheme",
"result": {
"fg": { "r": 255, "g": 255, "b": 255, "dark": false },
"bg": { "r": 127, "g": 127, "b": 127, "dark": true }
}
}
]-
fgandbgare objects with four keys each, in the orderr,g,b,dark. -
r/g/bare numbers0–255;darkis a boolean. - On failure the object carries
errorinstead and has noresult. - Unlike the text output, the JSON keeps both
darkflags, so the foreground type is available without a custom format.
// A one-line summary of both types
{ "type": "terminaltheme", "format": "fg {fg-type} / bg {bg-type}" }// Pick a logo variant from the background
{ "type": "terminaltheme", "format": "{bg-type}" }-
"Dark" in the default line describes the background only. The line ends with
[%s]filled fromresult.bg.dark, so a light-background / dark-foreground terminal still prints[Light]. Both types are in the JSON and in the format variables. -
COLORFGBGis the fallback, not the primary source. The escape-code query (OSC 10/OSC 11) runs first andCOLORFGBGis only consulted when it gets no parseable reply — so a terminal that answers the query ignores the variable completely. -
COLORFGBGis quantised to 16 colours. Its two numbers are indices into a fixed palette, and the values in that palette are the classic X11 ones (1is#CD0000, not#FF0000;7is#E5E5E5). An index outside0–15maps to black, and a value that does not parse as exactly two%dseparated by;is rejected outright. -
A missing
COLORFGBGand an unresponsive terminal means no output. The module reportsFailed to detect terminal themethroughffPrintError(), which is silent unlessdisplay.showErrorsistrue— the module then simply vanishes, exactly like the other terminal modules. -
The "dark" test is a luma threshold, not a perceptual one. It is
r * 299 + g * 587 + b * 114 < 128000, i.e. Rec. 601 luma below 128 on a 0–255 scale. A mid-grey background around#808080sits right at the boundary and can land either way. -
The escape query costs up to a second.
ffGetTerminalResponse()waits up toFF_IO_TERM_RESP_WAIT_MS(1000 ms) for the reply, so a terminal that does not implementOSC 10/OSC 11delays the module by that much before falling back toCOLORFGBG. The source records that Windows Terminal strips all\efrom its output, which is one such case. -
The same detection also controls
display.brightColor.ffOptionsInitDisplay()probes the theme withforceEnv = true— the environment path only, deliberately skipping the escape query "for performance" — and setsbrightColortofalsewhen the background is light. That happens at option-init time, whether or not theterminalthememodule is enabled, so exportingCOLORFGBGchanges the colours of unrelated modules. -
This module is not cached. Each call re-runs the detection, so under
--dynamic-intervalit re-queries the terminal on every round.
ffDetectTerminalTheme() fills an FFTerminalThemeResult — two FFTerminalThemeColor values
(uint8_t r, g, b plus a bool dark) — and then computes both dark flags. It is the only
detector in this area that takes a forceEnv argument:
if (!forceEnv && detectByEscapeCode(result)) return true;
return detectByEnv(result);ffPrintTerminalTheme() formats the default line as
#%02X%02X%02X (FG) - #%02X%02X%02X (BG) [%s], or pre-renders the two #RRGGBB strings and the
two type strings for the format engine. ffGenerateTerminalThemeJsonResult() writes the two
nested objects.
Two queries are sent back to back — \e]10;?\e\\ for the foreground and \e]11;?\e\\ for the
background — and the replies are parsed as rgb:RRRR/GGGG/BBBB with
%*[^0-9]10;rgb:%x/%x/%x … %*[^0-9]11;rgb:%x/%x/%x. The leading %*[^0-9] is what makes the parse
tolerant of the escape sequence itself being present or stripped. Components above 0x100 — a
terminal answering with 16-bit channels — make all three components of that colour be divided by
0x100.
COLORFGBG is split with sscanf(color, "%d;%d", &f, &g), and each number goes through
fgbgToColor(), a 16-entry switch over the classic ANSI palette (0 black, 1 #CD0000,
2 #00CD00, 3 #CDCD00, 4 #0000EE, 5 #CD00CD, 6 #00CDCD, 7 #E5E5E5, then the
bright variants 8–15, 8 being #7F7F7F and 15 #FFFFFF). Anything outside that range
becomes black.
{ "type": "terminaltheme", "format": "{fg-color}|{fg-type}|{bg-color}|{bg-type}" }