Add a couple of format c/f and c/b to emit colours.

This commit is contained in:
nicm
2026-07-01 13:12:17 +00:00
parent 724f85d275
commit e9396e59d9
5 changed files with 92 additions and 8 deletions

View File

@@ -232,7 +232,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
n = 1;
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
format_defaults(ft, NULL, NULL, NULL, NULL);
format_defaults(ft, tc, NULL, NULL, NULL);
format_add(ft, "notes_only", "%d", notes_only);
format_add(ft, "key_has_repeat", "%d", key_bindings_has_repeat(l, n));
format_add(ft, "key_string_width", "%u", cmd_list_keys_get_width(l, n));

View File

@@ -290,6 +290,58 @@ colour_tostring(int c)
return ("invalid");
}
/* Convert colour to an SGR escape sequence. */
const char *
colour_toescape(struct client *c, int colour, int bg)
{
static char s[32];
u_char r, g, b;
int n, flags = (TERM_256COLOURS|TERM_RGBCOLOURS);
u_int o = (bg ? 40 : 30);
if (c != NULL && (c->tty.flags & TTY_OPENED) && c->tty.term != NULL)
flags = c->tty.term->flags;
if (colour & COLOUR_FLAG_THEME) {
n = colour & 0xff;
if (c != NULL && (u_int)n < COLOUR_THEME_COUNT)
colour = c->theme_colours[n];
else
colour = colour_theme_terminal_colour(n);
}
if (colour == 8 || colour == 9) {
xsnprintf(s, sizeof s, "\033[%dm", o + 9);
return (s);
}
if ((~flags & TERM_RGBCOLOURS) & (colour & COLOUR_FLAG_RGB)) {
colour_split_rgb(colour, &r, &g, &b);
colour = colour_find_rgb(r, g, b);
}
if ((~flags & TERM_256COLOURS) & (colour & COLOUR_FLAG_256))
colour = colour_256to16(colour);
if (colour & COLOUR_FLAG_RGB) {
colour_split_rgb(colour, &r, &g, &b);
xsnprintf(s, sizeof s, "\033[%d;2;%u;%u;%um", o + 8, r, g, b);
return (s);
}
if (colour & COLOUR_FLAG_256) {
xsnprintf(s, sizeof s, "\033[%d;5;%um", o + 8, colour & 0xff);
return (s);
}
if (colour >= 0 && colour <= 7) {
xsnprintf(s, sizeof s, "\033[%dm", colour + o);
return (s);
}
if (colour >= 90 && colour <= 97) {
xsnprintf(s, sizeof s, "\033[%dm", colour + o - 30);
return (s);
}
return (NULL);
}
/* Convert background colour to theme. */
enum client_theme
colour_totheme(int c)

View File

@@ -121,6 +121,8 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_CLIENT_TERMCAP 0x1000000
#define FORMAT_CLIENT_TERMFEAT 0x2000000
#define FORMAT_CLIENT_ENVIRON 0x4000000
#define FORMAT_COLOUR_ESC_FG 0x8000000
#define FORMAT_COLOUR_ESC_BG 0x10000000
/* Limit on recursion. */
#define FORMAT_LOOP_LIMIT 100
@@ -4454,7 +4456,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
break;
/* Check single character modifiers with no arguments. */
if (strchr("labcdnwETSWPL!<>", cp[0]) != NULL &&
if (strchr("labdnwETSWPL!<>", cp[0]) != NULL &&
format_is_end(cp[1])) {
format_add_modifier(&list, count, cp, 1, NULL, 0);
cp++;
@@ -4476,7 +4478,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
}
/* Now try single character with arguments. */
if (strchr("ImCLNPSst=pReqW", cp[0]) == NULL)
if (strchr("ImCLNPSst=pReqWc", cp[0]) == NULL)
break;
c = cp[0];
@@ -5254,6 +5256,12 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
break;
case 'c':
modifiers |= FORMAT_COLOUR;
if (fm->argc < 1)
break;
if (strchr(fm->argv[0], 'f') != NULL)
modifiers |= FORMAT_COLOUR_ESC_FG;
if (strchr(fm->argv[0], 'b') != NULL)
modifiers |= FORMAT_COLOUR_ESC_BG;
break;
case 'd':
modifiers |= FORMAT_DIRNAME;
@@ -5452,11 +5460,28 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
/* Is this a colour? */
if (modifiers & FORMAT_COLOUR) {
new = format_expand1(es, copy);
if (modifiers & (FORMAT_COLOUR_ESC_FG|FORMAT_COLOUR_ESC_BG)) {
if (strcasecmp(new, "none") == 0)
value = xstrdup("\033[0m");
else if ((c = colour_fromstring(new)) == -1)
value = xstrdup("");
else {
if (modifiers & FORMAT_COLOUR_ESC_BG)
cp = colour_toescape(ft->c, c, 1);
else
cp = colour_toescape(ft->c, c, 0);
if (cp == NULL)
value = xstrdup("");
else
value = xstrdup(cp);
}
} else {
c = colour_fromstring(new);
if (c == -1 || (c = colour_force_rgb(c)) == -1)
value = xstrdup("");
else
xasprintf(&value, "%06x", c & 0xffffff);
}
free(new);
goto done;
}

6
tmux.1
View File

@@ -6694,6 +6694,12 @@ results in
replaces a
.Nm
colour by its six-digit hexadecimal RGB value.
If an argument of
.Ql f
or
.Ql b
is given, it will instead produce the SGR escape sequence to set the foreground
or background colour respectively.
.Pp
A limit may be placed on the length of the resultant string by prefixing it
by an

1
tmux.h
View File

@@ -3254,6 +3254,7 @@ void colour_split_rgb(int, u_char *, u_char *, u_char *);
int colour_force_rgb(int);
int colour_dim(int, u_int);
const char *colour_tostring(int);
const char *colour_toescape(struct client *, int, int);
enum client_theme colour_totheme(int);
int colour_fromstring(const char *);
const char *colour_theme_option(u_int, enum client_theme);