Skip to content

Commit 6460e96

Browse files
committed
Format: support syntax of {$ENV_VAR} in custom format
Fix #1541
1 parent 486ade0 commit 6460e96

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Features:
1616
* Capitalize `{type}`'s first letter in custom format (#1543, Display)
1717
* Support model name detection for s390x (CPU, Linux)
1818
* Support more Armbian variants detection (#1547, OS, Linux)
19+
* Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541)
20+
* This is another way to pass 3rd-party data to fastfetch besides `Custom` module.
1921

2022
Logo:
2123
* Update arch_old

src/common/format.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -259,24 +259,33 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
259259
continue;
260260
}
261261

262-
//test for constant, if so evaluate it
262+
//test for constant or env var, if so evaluate it
263263
if (firstChar == '$')
264264
{
265265
char* pend = NULL;
266266
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
267-
uint32_t index = (uint32_t) indexSigned;
268-
bool backward = indexSigned < 0;
269-
270-
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
267+
if (pend == placeholderValue.chars + 1)
271268
{
272-
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
273-
continue;
269+
// treat placeholder as an environment variable
270+
char* envValue = getenv(placeholderValue.chars + 1);
271+
if (envValue)
272+
ffStrbufAppendS(buffer, envValue);
273+
else
274+
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
274275
}
276+
else
277+
{
278+
// treat placeholder as a constant
279+
uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1);
275280

276-
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward
277-
? instance.config.display.constants.length - index
278-
: index - 1);
279-
ffStrbufAppend(buffer, item);
281+
if (*pend != '\0' || instance.config.display.constants.length <= index)
282+
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
283+
else
284+
{
285+
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index);
286+
ffStrbufAppend(buffer, item);
287+
}
288+
}
280289
continue;
281290
}
282291

src/data/help_format.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string.
2121
If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string.
2222
If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
2323

24+
In 2.36.0 or newer, `{$NUM}` can be specified to reference a constant defined in `display.constants`. `{$ENV_VAR}` can be specified to reference an environment variable.
25+
2426
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
2527
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
2628
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.

tests/format.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ int main(void)
113113
VERIFY("output({?1}OK{?}{/1}NOT OK{/})", "", "output(NOT OK)");
114114
}
115115

116+
{
117+
ffListInit(&instance.config.display.constants, sizeof(FFstrbuf));
118+
ffStrbufSetStatic(ffListAdd(&instance.config.display.constants), "CONST1");
119+
ffStrbufSetStatic(ffListAdd(&instance.config.display.constants), "CONST2");
120+
setenv("FF_TEST", "ENVVAR", 1);
121+
VERIFY("output({$FF_TEST})", "", "output(ENVVAR)");
122+
VERIFY("output({$1})", "", "output(CONST1)");
123+
VERIFY("output({$FF_TEST}{$1})", "", "output(ENVVARCONST1)");
124+
VERIFY("output({$1}{$FF_TEST})", "", "output(CONST1ENVVAR)");
125+
VERIFY("output({$FF_TEST}{$FF_TEST})", "", "output(ENVVARENVVAR)");
126+
VERIFY("output({$1}{$-1})", "", "output(CONST1CONST2)");
127+
128+
VERIFY("output({$FF_INVAL})", "", "output({$FF_INVAL})");
129+
VERIFY("output({$9}{$0}${-9})", "", "output({$9}{$0}${-9})");
130+
VERIFY("output({$1NO})", "", "output({$1NO})");
131+
ffListDestroy(&instance.config.display.constants);
132+
}
133+
116134
//Success
117135
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
118136
}

0 commit comments

Comments
 (0)