diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2022-04-15 13:31:22 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2022-04-15 14:45:08 -0400 |
commit | 7241d6cc35134fcb5ec6dfa81bbd01e430b2415f (patch) | |
tree | 3b3dbde25dff9430ca644f680249a6add224f213 | |
parent | a571aa9ef6f3dc2099ee33c5040f8c54776ddece (diff) | |
download | bfs-7241d6cc35134fcb5ec6dfa81bbd01e430b2415f.tar.xz |
color: Support a separate $BFS_COLORS environment variable
-rw-r--r-- | bfs.1 | 14 | ||||
-rw-r--r-- | color.c | 123 | ||||
-rw-r--r-- | color.h | 6 | ||||
-rw-r--r-- | parse.c | 2 | ||||
-rwxr-xr-x | tests.sh | 9 |
5 files changed, 84 insertions, 70 deletions
@@ -715,16 +715,26 @@ Yes/no prompts (e.g. from .BR \-ok ) will also be interpreted according to the current locale. .RE -.TP +.PP .B LS_COLORS +.br +.B BFS_COLORS +.RS Controls the colors used when displaying file paths if .B \-color is enabled. .B bfs -interprets this environment variable is interpreted the same way GNU +interprets +.B LS_COLORS +the same way GNU .BR ls (1) does (see .BR dir_colors (5)). +.B BFS_COLORS +can be used to customize +.B bfs +without affecting other commands. +.RE .TP .B NO_COLOR Causes @@ -34,9 +34,6 @@ #include <time.h> #include <unistd.h> -/** - * The parsed form of LS_COLORS. - */ struct colors { char *reset; char *leftcode; @@ -198,7 +195,7 @@ static const char *get_ext_color(const struct colors *colors, const char *filena } /** - * Parse a chunk of LS_COLORS that may have escape sequences. The supported + * Parse a chunk of $LS_COLORS that may have escape sequences. The supported * escapes are: * * \a, \b, \f, \n, \r, \t, \v: @@ -358,7 +355,66 @@ fail: return NULL; } -struct colors *parse_colors(const char *ls_colors) { +/** Parse the GNU $LS_COLORS format. */ +static void parse_gnu_ls_colors(struct colors *colors, const char *ls_colors) { + for (const char *chunk = ls_colors, *next; chunk; chunk = next) { + if (chunk[0] == '*') { + char *key = unescape(chunk + 1, '=', &next); + if (!key) { + continue; + } + + char *value = unescape(next, ':', &next); + if (value) { + if (set_ext_color(colors, key, value) != 0) { + dstrfree(value); + } + } + + dstrfree(key); + } else { + const char *equals = strchr(chunk, '='); + if (!equals) { + break; + } + + char *value = unescape(equals + 1, ':', &next); + if (!value) { + continue; + } + + char *key = strndup(chunk, equals - chunk); + if (!key) { + dstrfree(value); + continue; + } + + // All-zero values should be treated like NULL, to fall + // back on any other relevant coloring for that file + if (strspn(value, "0") == strlen(value) + && strcmp(key, "rs") != 0 + && strcmp(key, "lc") != 0 + && strcmp(key, "rc") != 0 + && strcmp(key, "ec") != 0) { + dstrfree(value); + value = NULL; + } + + if (set_color(colors, key, value) != 0) { + dstrfree(value); + } + free(key); + } + } + + if (colors->link && strcmp(colors->link, "target") == 0) { + colors->link_as_target = true; + dstrfree(colors->link); + colors->link = NULL; + } +} + +struct colors *parse_colors() { struct colors *colors = malloc(sizeof(struct colors)); if (!colors) { return NULL; @@ -422,61 +478,8 @@ struct colors *parse_colors(const char *ls_colors) { return NULL; } - for (const char *chunk = ls_colors, *next; chunk; chunk = next) { - if (chunk[0] == '*') { - char *key = unescape(chunk + 1, '=', &next); - if (!key) { - continue; - } - - char *value = unescape(next, ':', &next); - if (value) { - if (set_ext_color(colors, key, value) != 0) { - dstrfree(value); - } - } - - dstrfree(key); - } else { - const char *equals = strchr(chunk, '='); - if (!equals) { - break; - } - - char *value = unescape(equals + 1, ':', &next); - if (!value) { - continue; - } - - char *key = strndup(chunk, equals - chunk); - if (!key) { - dstrfree(value); - continue; - } - - // All-zero values should be treated like NULL, to fall - // back on any other relevant coloring for that file - if (strspn(value, "0") == strlen(value) - && strcmp(key, "rs") != 0 - && strcmp(key, "lc") != 0 - && strcmp(key, "rc") != 0 - && strcmp(key, "ec") != 0) { - dstrfree(value); - value = NULL; - } - - if (set_color(colors, key, value) != 0) { - dstrfree(value); - } - free(key); - } - } - - if (colors->link && strcmp(colors->link, "target") == 0) { - colors->link_as_target = true; - dstrfree(colors->link); - colors->link = NULL; - } + parse_gnu_ls_colors(colors, getenv("LS_COLORS")); + parse_gnu_ls_colors(colors, getenv("BFS_COLORS")); return colors; } @@ -27,18 +27,16 @@ #include <stdio.h> /** - * A lookup table for colors. + * A color scheme. */ struct colors; /** * Parse a color table. * - * @param ls_colors - * A color table in the LS_COLORS environment variable format. * @return The parsed color table. */ -struct colors *parse_colors(const char *ls_colors); +struct colors *parse_colors(void); /** * Free a color table. @@ -3856,7 +3856,7 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { use_color = COLOR_NEVER; } - ctx->colors = parse_colors(getenv("LS_COLORS")); + ctx->colors = parse_colors(); if (!ctx->colors) { ctx->colors_error = errno; } @@ -28,6 +28,9 @@ export MSAN_OPTIONS="abort_on_error=1" export TSAN_OPTIONS="abort_on_error=1" export UBSAN_OPTIONS="abort_on_error=1" +export LS_COLORS="" +unset BFS_COLORS + if [ -t 1 ]; then BLD=$(printf '\033[01m') RED=$(printf '\033[01;31m') @@ -2452,7 +2455,7 @@ function test_printf_must_be_numeric() { } function test_printf_color() { - LS_COLORS="" bfs_diff -color -path './rainbow*' -printf '%H %h %f %p %P %l\n' + bfs_diff -color -path './rainbow*' -printf '%H %h %f %p %P %l\n' } function test_fprintf() { @@ -2552,11 +2555,11 @@ function test_extra_paren() { } function test_color() { - LS_COLORS="" bfs_diff rainbow -color + bfs_diff rainbow -color } function test_color_L() { - LS_COLORS="" bfs_diff -L rainbow -color + bfs_diff -L rainbow -color } function test_color_rs_lc_rc_ec() { |