-
-
Notifications
You must be signed in to change notification settings - Fork 898
Custom
Print a custom string, with or without key
| Module type | custom |
| Default order | — (no defaultOrder) |
| Module source | src/modules/custom/custom.c |
| Detection source | — |
Prints a literal string. It is the module you want for a static line, a separator-like label, or a value that comes from the environment:
hello
The default key is a single space, so nothing precedes the text. Give it a key and you get an
ordinary key: value line:
Note: hello
| Platform | Implementation | Notes |
|---|---|---|
| Everywhere | src/modules/custom/custom.c |
Platform independent |
No detection layer, no OS calls — the text is taken verbatim from the config.
| Option | Type | Default | Description |
|---|---|---|---|
format |
string | – | The text to print. This is where your text goes, not text. |
key |
string | " " |
Key text. A single space hides the key and its separator. |
keyColor |
color | – | Overrides display.color.keys. |
keyIcon |
string | built-in glyph | The icon printed when display.key.type includes the icon bit. Set it to any glyph you like, or to "" to print none. |
keyWidth |
integer | – | Overrides display.key.width. |
outputColor |
color | – | Overrides display.color.output. |
condition |
object | – | See Configuration. |
The keys above are the entire accepted set. text is not a valid key here — that is the
Command module's option.
Beware of the key default: because the initial key is a single space, a custom module without an
explicit key prints only its text. Writing "key": "" does not hide it either — see
Pitfalls.
custom publishes no format variables; fastfetch -h custom-format prints nothing.
The format string is still parsed as a format string, so it has access to the global syntax that
does not depend on module arguments:
| Syntax | Meaning |
|---|---|
{$NAME} |
Value of the environment variable NAME (empty if unset) |
{$1} … {$N}
|
Constant from display.constants (1-based; negative counts from the end) |
{#RRGGBB}, {#name}
|
Inline color escape |
{{ |
A literal {
|
Note the $ in {$NAME}: {HOME} is not substituted and is printed literally as {HOME}.
{ "modules": [ { "type": "custom", "format": "HOME={$HOME} NOPE={$DOES_NOT_EXIST}" } ] }HOME=/home/user NOPE={$DOES_NOT_EXIST}
An unset variable leaves the placeholder visible, which is a useful sanity check.
The JSON result is the rendered format string — the same value the console prints:
{ "type": "Custom", "result": "hello" }Placeholders are resolved first, so format: "HOME={$HOME}" exports the expanded text, and a
qjs: / lua: format exports the script's output, not the script itself.
A failure inside such a script is reported as error with no result:
{ "type": "Custom", "error": "Qjs runtime error: SyntaxError: expecting ';'" }A plain format never fails, though: an unknown placeholder such as {bogus} is emitted verbatim
rather than treated as an error, so it lands in result unchanged.
A static label with a value that comes from the environment:
{
"modules": [
{ "type": "custom", "key": "Projects", "format": "{$HOME}/projects" }
]
}A heading with inline color — note the single closing brace, since only {{ is an escape and a lone
} is literal:
{ "type": "custom", "format": "{#blue}{{ System }{#}" }A blank line as spacing:
{ "type": "custom", "key": " ", "format": " " }Constants are handy for repeated values:
{
"display": { "constants": ["/home/user/projects"] },
"modules": [ { "type": "custom", "key": "Projects", "format": "{$1}" } ]
}-
"key": ""shows the module name, it does not hide it. The runtime falls back toCustom: hellowhen the key is empty, so a single space is what hides the key and its separator. The sharedkeydefinition indoc/json_schema.jsonsays exactly that — “use a single space to hide the key” — andcustomnow reuses it rather than carrying its own wording. -
The JSON
resultis the rendered text, not yourformatstring. Placeholders are already expanded and aqjs:/lua:script has already run, so the raw template is not recoverable from--format json; use--gen-configif you need the config form back.break,colorsandseparatorremain the only modules with no JSON result at all. -
formatis parsed, not printed verbatim. A{that is not part of a placeholder must be written{{, and any{$…}sequence is resolved. A Windows path such asC:\{$X}is a footgun; prefer forward slashes or escape the brace. -
An
#-style color insideformatis emitted as\e[<color>mand relies on the following text to reset. Follow it with{#}or a named color to avoid bleeding into the next line. -
\eonly works in a.json5config..jsonand.jsoncare read with the strict reader, which rejects the escape withinvalid escaped sequence in string.{#name}/{#RRGGBB}(as used above) works in every dialect, as does\u001b. See Global. -
customhas no detection layer, so it never fails and never reports an error — a mistake informatis invisible. Test with--pipeto see the raw output. -
Module options are JSON-only. There is no
--custom-formatflag any more.
ffPrintCustom() is a two-line function:
bool ffPrintCustom(FFCustomOptions* options) {
ffPrintFormat(FF_MODULE_GET_DISPLAY_NAME(Custom), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, 0, ((FFformatarg[]) {}));
return true;
}It delegates everything to ffPrintFormat() (src/common/impl/format.c) with zero format
arguments — that is why no {variable} resolves and why fastfetch -h custom-format has nothing to
list. What does still work is the argument-independent syntax: the {$…} branch of the parser reads
getenv() for a name and instance.config.display.constants for an index, neither of which depends
on the module's argument list.
ffInitCustomOptions() sets the icon and then ffStrbufSetStatic(&options->moduleArgs.key, " "), so
the key is a space rather than empty. FFCustomOptions holds nothing but moduleArgs
(src/modules/custom/option.h), so the whole configuration surface is the seven shared keys.
ffParseCustomJsonObject() accepts exactly what ffJsonConfigParseModuleArgs() understands and
reports anything else through ffPrintError(), which is silent unless display.showErrors is set.
{ "modules": [ { "type": "custom", "key": "Note", "format": "hello" } ] }