Skip to content

Commit 29eaa35

Browse files
committed
Color: support #RGB and #RRGGBB
Fix #1694
1 parent 97c89c3 commit 29eaa35

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,10 +1834,18 @@ if (BUILD_TESTS)
18341834
PRIVATE libfastfetch
18351835
)
18361836

1837+
add_executable(fastfetch-test-color
1838+
tests/color.c
1839+
)
1840+
target_link_libraries(fastfetch-test-color
1841+
PRIVATE libfastfetch
1842+
)
1843+
18371844
enable_testing()
18381845
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
18391846
add_test(NAME test-list COMMAND fastfetch-test-list)
18401847
add_test(NAME test-format COMMAND fastfetch-test-format)
1848+
add_test(NAME test-color COMMAND fastfetch-test-color)
18411849
endif()
18421850

18431851
##################

src/common/option.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
177177
if (ffCharIsEnglishAlphabet(value[0]))
178178
{
179179
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
180+
else FF_APPEND_COLOR_CODE_COND(bold_, FF_COLOR_MODE_BOLD)
180181
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
181182
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
182183
else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC)
@@ -212,6 +213,35 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
212213
exit(479);
213214
}
214215
}
216+
else if (value[0] == '#')
217+
{
218+
// RGB color
219+
++value;
220+
char* pend = NULL;
221+
uint32_t rgb = (uint32_t) strtoul(value, &pend, 16);
222+
if (pend == value) {
223+
fprintf(stderr, "Error: invalid RGB color code found: %s\n", value);
224+
exit(479);
225+
}
226+
if (pend - value > 6) {
227+
fprintf(stderr, "Error: RGB color code too long: %s\n", value);
228+
exit(479);
229+
}
230+
else if (pend - value == 3) {
231+
rgb = ((rgb & 0xF00) >> 8) * 0x110000 +
232+
((rgb & 0x0F0) >> 4) * 0x001100 +
233+
((rgb & 0x00F) >> 0) * 0x000011;
234+
}
235+
else if (pend - value != 6) {
236+
fprintf(stderr, "Error: invalid RGB color code length: %s\n", value);
237+
exit(479);
238+
}
239+
240+
uint32_t r = rgb >> 16, g = (rgb >> 8) & 0xFF, b = rgb & 0xFF;
241+
ffStrbufAppendF(buffer, FF_COLOR_FG_RGB "%u;%u;%u", r, g, b);
242+
value = pend;
243+
continue;
244+
}
215245
ffStrbufAppendC(buffer, *value);
216246
++value;
217247

tests/color.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include "common/format.h"
2+
#include "util/textModifier.h"
3+
#include "fastfetch.h"
4+
5+
#include <stdlib.h>
6+
7+
static void verify(const char* color, const char* expected, int lineNo)
8+
{
9+
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
10+
ffOptionParseColorNoClear(color, &result);
11+
if (!ffStrbufEqualS(&result, expected))
12+
{
13+
fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] %s: expected \"%s\", got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET, lineNo, color, expected, result.chars);
14+
exit(1);
15+
}
16+
}
17+
18+
#define VERIFY(color, expected) verify((color), (expected), __LINE__)
19+
20+
int main(void)
21+
{
22+
instance.config.display.pipe = true;
23+
// Initialize dummy config colors for property tests
24+
ffStrbufInitS(&instance.config.display.colorKeys, "94"); // light_blue
25+
ffStrbufInitS(&instance.config.display.colorTitle, "95"); // light_magenta
26+
27+
{
28+
VERIFY("", "");
29+
VERIFY("1", "1");
30+
31+
VERIFY("red", "31");
32+
VERIFY("light_green", "92");
33+
VERIFY("default", "39");
34+
VERIFY("blue", "34");
35+
VERIFY("light_cyan", "96");
36+
37+
VERIFY("bold_red", "1;31");
38+
VERIFY("dim_light_yellow", "2;93");
39+
VERIFY("italic_underline_green", "3;4;32");
40+
VERIFY("reset_blue", "0;34"); // Reset followed by color
41+
42+
VERIFY("#ff0000", "38;2;255;0;0"); // RRGGBB
43+
VERIFY("#0f0", "38;2;0;255;0"); // RGB
44+
VERIFY("#123456", "38;2;18;52;86");
45+
VERIFY("#abc", "38;2;170;187;204");
46+
47+
VERIFY("bold_#ff00ff", "1;38;2;255;0;255");
48+
VERIFY("underline_#123", "4;38;2;17;34;51");
49+
50+
VERIFY("\e[32m", "32"); // Direct ANSI code
51+
VERIFY("\e[1;94m", "1;94"); // Direct ANSI code with mode
52+
53+
// Property colors (ensure dummy config colors are set)
54+
VERIFY("keys", "94");
55+
VERIFY("title", "95");
56+
VERIFY("bold_keys", "1;94");
57+
}
58+
59+
// Clean up dummy config colors
60+
ffStrbufDestroy(&instance.config.display.colorKeys);
61+
ffStrbufDestroy(&instance.config.display.colorTitle);
62+
63+
//Success
64+
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
65+
}

0 commit comments

Comments
 (0)