mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Allow escaping , and } with # in #{}; GitHub issue 1332.
This commit is contained in:
parent
f2f9605c63
commit
2a04665626
46
format.c
46
format.c
@ -837,18 +837,22 @@ found:
|
|||||||
return (copy);
|
return (copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip until comma. */
|
/* Skip until end. */
|
||||||
static char *
|
static const char *
|
||||||
format_skip(char *s)
|
format_skip(const char *s, char end)
|
||||||
{
|
{
|
||||||
int brackets = 0;
|
int brackets = 0;
|
||||||
|
|
||||||
for (; *s != '\0'; s++) {
|
for (; *s != '\0'; s++) {
|
||||||
if (*s == '{')
|
if (*s == '#' && s[1] == '{')
|
||||||
brackets++;
|
brackets++;
|
||||||
|
if (*s == '#' && strchr(",#{}", s[1]) != NULL) {
|
||||||
|
s++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (*s == '}')
|
if (*s == '}')
|
||||||
brackets--;
|
brackets--;
|
||||||
if (*s == ',' && brackets == 0)
|
if (*s == end && brackets == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*s == '\0')
|
if (*s == '\0')
|
||||||
@ -862,7 +866,7 @@ format_choose(char *s, char **left, char **right)
|
|||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
cp = format_skip(s);
|
cp = (char *)format_skip(s, ',');
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
@ -892,6 +896,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
size_t valuelen, newlen, fromlen, tolen, used;
|
size_t valuelen, newlen, fromlen, tolen, used;
|
||||||
long limit = 0;
|
long limit = 0;
|
||||||
int modifiers = 0, compare = 0, search = 0;
|
int modifiers = 0, compare = 0, search = 0;
|
||||||
|
int literal = 0;
|
||||||
|
|
||||||
/* Make a copy of the key. */
|
/* Make a copy of the key. */
|
||||||
copy0 = copy = xmalloc(keylen + 1);
|
copy0 = copy = xmalloc(keylen + 1);
|
||||||
@ -900,6 +905,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
|
|
||||||
/* Is there a length limit or whatnot? */
|
/* Is there a length limit or whatnot? */
|
||||||
switch (copy[0]) {
|
switch (copy[0]) {
|
||||||
|
case 'l':
|
||||||
|
if (copy[1] != ':')
|
||||||
|
break;
|
||||||
|
literal = 1;
|
||||||
|
copy += 2;
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (copy[1] != ':')
|
if (copy[1] != ':')
|
||||||
break;
|
break;
|
||||||
@ -988,6 +999,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Is this a literal string? */
|
||||||
|
if (literal) {
|
||||||
|
value = xstrdup(copy);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is this a comparison or a conditional? */
|
/* Is this a comparison or a conditional? */
|
||||||
if (search) {
|
if (search) {
|
||||||
/* Search in pane. */
|
/* Search in pane. */
|
||||||
@ -1019,7 +1036,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
free(left);
|
free(left);
|
||||||
} else if (*copy == '?') {
|
} else if (*copy == '?') {
|
||||||
/* Conditional: check first and choose second or third. */
|
/* Conditional: check first and choose second or third. */
|
||||||
ptr = format_skip(copy);
|
ptr = (char *)format_skip(copy, ',');
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
@ -1082,6 +1099,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Expand the buffer and copy in the value. */
|
/* Expand the buffer and copy in the value. */
|
||||||
|
done:
|
||||||
valuelen = strlen(value);
|
valuelen = strlen(value);
|
||||||
while (*len - *off < valuelen + 1) {
|
while (*len - *off < valuelen + 1) {
|
||||||
*buf = xreallocarray(*buf, 2, *len);
|
*buf = xreallocarray(*buf, 2, *len);
|
||||||
@ -1179,14 +1197,8 @@ format_expand(struct format_tree *ft, const char *fmt)
|
|||||||
fmt += n + 1;
|
fmt += n + 1;
|
||||||
continue;
|
continue;
|
||||||
case '{':
|
case '{':
|
||||||
brackets = 1;
|
ptr = format_skip(fmt - 2, '}');
|
||||||
for (ptr = fmt; *ptr != '\0'; ptr++) {
|
if (ptr == NULL)
|
||||||
if (*ptr == '{')
|
|
||||||
brackets++;
|
|
||||||
if (*ptr == '}' && --brackets == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*ptr != '}' || brackets != 0)
|
|
||||||
break;
|
break;
|
||||||
n = ptr - fmt;
|
n = ptr - fmt;
|
||||||
|
|
||||||
@ -1194,12 +1206,14 @@ format_expand(struct format_tree *ft, const char *fmt)
|
|||||||
break;
|
break;
|
||||||
fmt += n + 1;
|
fmt += n + 1;
|
||||||
continue;
|
continue;
|
||||||
|
case '}':
|
||||||
case '#':
|
case '#':
|
||||||
|
case ',':
|
||||||
while (len - off < 2) {
|
while (len - off < 2) {
|
||||||
buf = xreallocarray(buf, 2, len);
|
buf = xreallocarray(buf, 2, len);
|
||||||
len *= 2;
|
len *= 2;
|
||||||
}
|
}
|
||||||
buf[off++] = '#';
|
buf[off++] = ch;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
s = NULL;
|
s = NULL;
|
||||||
|
12
tmux.1
12
tmux.1
@ -3542,11 +3542,17 @@ The possible variables are listed in the table below, or the name of a
|
|||||||
.Nm
|
.Nm
|
||||||
option may be used for an option's value.
|
option may be used for an option's value.
|
||||||
Some variables have a shorter alias such as
|
Some variables have a shorter alias such as
|
||||||
.Ql #S ,
|
.Ql #S ;
|
||||||
and
|
|
||||||
.Ql ##
|
.Ql ##
|
||||||
is replaced by a single
|
is replaced by a single
|
||||||
.Ql # .
|
.Ql # ,
|
||||||
|
.Ql #,
|
||||||
|
by a
|
||||||
|
.Ql \&,
|
||||||
|
and
|
||||||
|
.Ql #}
|
||||||
|
by a
|
||||||
|
.Ql } .
|
||||||
.Pp
|
.Pp
|
||||||
Conditionals are available by prefixing with
|
Conditionals are available by prefixing with
|
||||||
.Ql \&?
|
.Ql \&?
|
||||||
|
Loading…
Reference in New Issue
Block a user