Merge branch 'master' into command_parser

This commit is contained in:
Nicholas Marriott
2026-07-01 14:53:15 +01:00
5 changed files with 92 additions and 8 deletions

View File

@@ -251,7 +251,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
n = 1; n = 1;
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0); 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, "notes_only", "%d", notes_only);
format_add(ft, "key_has_repeat", "%d", key_bindings_has_repeat(l, n)); 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)); 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"); 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. */ /* Convert background colour to theme. */
enum client_theme enum client_theme
colour_totheme(int c) 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_TERMCAP 0x1000000
#define FORMAT_CLIENT_TERMFEAT 0x2000000 #define FORMAT_CLIENT_TERMFEAT 0x2000000
#define FORMAT_CLIENT_ENVIRON 0x4000000 #define FORMAT_CLIENT_ENVIRON 0x4000000
#define FORMAT_COLOUR_ESC_FG 0x8000000
#define FORMAT_COLOUR_ESC_BG 0x10000000
/* Limit on recursion. */ /* Limit on recursion. */
#define FORMAT_LOOP_LIMIT 100 #define FORMAT_LOOP_LIMIT 100
@@ -4472,7 +4474,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
break; break;
/* Check single character modifiers with no arguments. */ /* 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_is_end(cp[1])) {
format_add_modifier(&list, count, cp, 1, NULL, 0); format_add_modifier(&list, count, cp, 1, NULL, 0);
cp++; cp++;
@@ -4494,7 +4496,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
} }
/* Now try single character with arguments. */ /* Now try single character with arguments. */
if (strchr("ImCLNPSst=pReqW", cp[0]) == NULL) if (strchr("ImCLNPSst=pReqWc", cp[0]) == NULL)
break; break;
c = cp[0]; c = cp[0];
@@ -5272,6 +5274,12 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
break; break;
case 'c': case 'c':
modifiers |= FORMAT_COLOUR; 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; break;
case 'd': case 'd':
modifiers |= FORMAT_DIRNAME; modifiers |= FORMAT_DIRNAME;
@@ -5470,11 +5478,28 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
/* Is this a colour? */ /* Is this a colour? */
if (modifiers & FORMAT_COLOUR) { if (modifiers & FORMAT_COLOUR) {
new = format_expand1(es, copy); new = format_expand1(es, copy);
c = colour_fromstring(new); if (modifiers & (FORMAT_COLOUR_ESC_FG|FORMAT_COLOUR_ESC_BG)) {
if (c == -1 || (c = colour_force_rgb(c)) == -1) if (strcasecmp(new, "none") == 0)
value = xstrdup(""); value = xstrdup("\033[0m");
else else if ((c = colour_fromstring(new)) == -1)
xasprintf(&value, "%06x", c & 0xffffff); 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); free(new);
goto done; goto done;
} }

6
tmux.1
View File

@@ -6698,6 +6698,12 @@ results in
replaces a replaces a
.Nm .Nm
colour by its six-digit hexadecimal RGB value. 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 .Pp
A limit may be placed on the length of the resultant string by prefixing it A limit may be placed on the length of the resultant string by prefixing it
by an by an

1
tmux.h
View File

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