mirror of
https://github.com/openbsd/src.git
synced 2026-06-18 07:13:36 +02:00
Add an I format modifier to get some bits of information about a client
(terminal features, capabilities and environment).
This commit is contained in:
+49
-3
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: format.c,v 1.375 2026/06/13 08:59:52 nicm Exp $ */
|
||||
/* $OpenBSD: format.c,v 1.376 2026/06/13 09:17:29 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -118,6 +118,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
||||
#define FORMAT_REPEAT 0x200000
|
||||
#define FORMAT_QUOTE_ARGUMENTS 0x400000
|
||||
#define FORMAT_RELATIVE 0x800000
|
||||
#define FORMAT_CLIENT_TERMCAP 0x1000000
|
||||
#define FORMAT_CLIENT_TERMFEAT 0x2000000
|
||||
#define FORMAT_CLIENT_ENVIRON 0x4000000
|
||||
|
||||
/* Limit on recursion. */
|
||||
#define FORMAT_LOOP_LIMIT 100
|
||||
@@ -4404,7 +4407,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
||||
|
||||
/*
|
||||
* Modifiers are a ; separated list of the forms:
|
||||
* l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,R,<,>
|
||||
* l,m,C,a,b,c,d,I,n,t,w,q,E,T,S,W,P,R,<,>
|
||||
* =a
|
||||
* =/a
|
||||
* =/a/
|
||||
@@ -4445,7 +4448,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
||||
}
|
||||
|
||||
/* Now try single character with arguments. */
|
||||
if (strchr("mCLNPSst=pReqW", cp[0]) == NULL)
|
||||
if (strchr("ImCLNPSst=pReqW", cp[0]) == NULL)
|
||||
break;
|
||||
c = cp[0];
|
||||
|
||||
@@ -5086,6 +5089,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
struct format_modifier *bool_op_n = NULL;
|
||||
u_int i, count, nsub = 0, nrep;
|
||||
struct format_expand_state next;
|
||||
struct environ_entry *envent;
|
||||
|
||||
/* Set sorting defaults. */
|
||||
sc->order = SORT_ORDER;
|
||||
@@ -5168,6 +5172,16 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
case 'n':
|
||||
modifiers |= FORMAT_LENGTH;
|
||||
break;
|
||||
case 'I':
|
||||
if (fm->argc < 1)
|
||||
break;
|
||||
if (strchr(fm->argv[0], 'f') != NULL)
|
||||
modifiers |= FORMAT_CLIENT_TERMFEAT;
|
||||
if (strchr(fm->argv[0], 'c') != NULL)
|
||||
modifiers |= FORMAT_CLIENT_TERMCAP;
|
||||
if (strchr(fm->argv[0], 'e') != NULL)
|
||||
modifiers |= FORMAT_CLIENT_ENVIRON;
|
||||
break;
|
||||
case 't':
|
||||
modifiers |= FORMAT_TIMESTRING;
|
||||
if (fm->argc < 1)
|
||||
@@ -5295,6 +5309,38 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up client capability, feature or environment. */
|
||||
if ((modifiers & FORMAT_CLIENT_TERMCAP) ||
|
||||
(modifiers & FORMAT_CLIENT_TERMFEAT) ||
|
||||
(modifiers & FORMAT_CLIENT_ENVIRON)) {
|
||||
if (ft->c == NULL ||
|
||||
ft->c->tty.term == NULL ||
|
||||
ft->c->flags & CLIENT_UNATTACHEDFLAGS) {
|
||||
value = xstrdup("");
|
||||
goto done;
|
||||
}
|
||||
if (modifiers & FORMAT_CLIENT_TERMCAP) {
|
||||
if (tty_term_has_name(ft->c->tty.term, copy))
|
||||
value = xstrdup("1");
|
||||
else
|
||||
value = xstrdup("0");
|
||||
}
|
||||
if (modifiers & FORMAT_CLIENT_TERMFEAT) {
|
||||
if (tty_feature_present(ft->c->tty.term, copy))
|
||||
value = xstrdup("1");
|
||||
else
|
||||
value = xstrdup("0");
|
||||
}
|
||||
if (modifiers & FORMAT_CLIENT_ENVIRON) {
|
||||
envent = environ_find(ft->c->environ, copy);
|
||||
if (envent != NULL && envent->value != NULL)
|
||||
value = xstrdup(envent->value);
|
||||
else
|
||||
value = xstrdup("");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Is this a literal string? */
|
||||
if (modifiers & FORMAT_LITERAL) {
|
||||
format_log(es, "literal string is '%s'", copy);
|
||||
|
||||
+19
-1
@@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.1081 2026/06/13 08:59:52 nicm Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.1082 2026/06/13 09:17:29 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@@ -6429,6 +6429,24 @@ see
|
||||
.Xr strftime 3 .
|
||||
.Pp
|
||||
The
|
||||
.Ql I:\&
|
||||
prefix will interrogate the client.
|
||||
.Ql I/f
|
||||
will be true if
|
||||
.Nm
|
||||
believes that the client supports the given terminal feature, for example
|
||||
.Ql I/f:RGB ,
|
||||
.Ql I/c
|
||||
will be true if a client has the given
|
||||
.Xr terminfo 3
|
||||
capability, for example
|
||||
.Ql I/c:smcup ,
|
||||
and
|
||||
.Ql I/e
|
||||
gives the value of a client environment variable, for example
|
||||
.Ql #{I/e:FOO} .
|
||||
.Pp
|
||||
The
|
||||
.Ql b:\&
|
||||
and
|
||||
.Ql d:\&
|
||||
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1346 2026/06/11 19:13:34 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1347 2026/06/13 09:17:29 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -2729,6 +2729,7 @@ int tty_term_read_list(const char *, int, char ***, u_int *,
|
||||
char **);
|
||||
void tty_term_free_list(char **, u_int);
|
||||
int tty_term_has(struct tty_term *, enum tty_code_code);
|
||||
int tty_term_has_name(struct tty_term *, const char *);
|
||||
const char *tty_term_string(struct tty_term *, enum tty_code_code);
|
||||
const char *tty_term_string_i(struct tty_term *, enum tty_code_code, int);
|
||||
const char *tty_term_string_ii(struct tty_term *, enum tty_code_code, int,
|
||||
@@ -2746,6 +2747,7 @@ const char *tty_term_describe(struct tty_term *, enum tty_code_code);
|
||||
/* tty-features.c */
|
||||
void tty_add_features(int *, const char *, const char *);
|
||||
const char *tty_get_features(int);
|
||||
int tty_feature_present(struct tty_term *, const char *);
|
||||
int tty_apply_features(struct tty_term *, int);
|
||||
void tty_default_features(int *, const char *, u_int);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty-features.c,v 1.36 2026/05/13 10:24:57 nicm Exp $ */
|
||||
/* $OpenBSD: tty-features.c,v 1.37 2026/06/13 09:17:29 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -432,6 +432,45 @@ tty_get_features(int feat)
|
||||
return (s);
|
||||
}
|
||||
|
||||
int
|
||||
tty_feature_present(struct tty_term *term, const char *name)
|
||||
{
|
||||
const struct tty_feature *tf = NULL;
|
||||
const char *const *capability;
|
||||
u_int i;
|
||||
char *copy;
|
||||
|
||||
for (i = 0; i < nitems(tty_features); i++) {
|
||||
tf = tty_features[i];
|
||||
if (strcmp(tf->name, name) == 0) {
|
||||
if (term->features & (1 << i))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't just have the feature flag set. Check if the capabilities
|
||||
* supported by the client are actual set instead.
|
||||
*/
|
||||
if (tf == NULL || strcmp(name, "ignorefkeys") == 0)
|
||||
return (0);
|
||||
if (tf->flags != 0 && (term->flags & tf->flags) != tf->flags)
|
||||
return (0);
|
||||
capability = tf->capabilities;
|
||||
while (*capability != NULL) {
|
||||
copy = xstrdup(*capability);
|
||||
copy[strcspn(copy, "=")] = '\0';
|
||||
if (!tty_term_has_name(term, copy)) {
|
||||
free(copy);
|
||||
return (0);
|
||||
}
|
||||
free(copy);
|
||||
capability++;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
tty_apply_features(struct tty_term *term, int feat)
|
||||
{
|
||||
|
||||
+13
-1
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty-term.c,v 1.105 2026/04/22 07:25:17 nicm Exp $ */
|
||||
/* $OpenBSD: tty-term.c,v 1.106 2026/06/13 09:17:29 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -765,6 +765,18 @@ tty_term_has(struct tty_term *term, enum tty_code_code code)
|
||||
return (term->codes[code].type != TTYCODE_NONE);
|
||||
}
|
||||
|
||||
int
|
||||
tty_term_has_name(struct tty_term *term, const char *name)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < tty_term_ncodes(); i++) {
|
||||
if (strcmp(tty_term_codes[i].name, name) == 0)
|
||||
return (tty_term_has(term, i));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char *
|
||||
tty_term_string(struct tty_term *term, enum tty_code_code code)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user