summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2018-05-22 08:49:12 +0000
committernicm <nicm>2018-05-22 08:49:12 +0000
commit2a04665626959dd57a88db2fd42813877e7f7fde (patch)
tree338682dfbb48d775858c1eb03403f95cc7f8e8b6
parentf2f9605c632b7cc953e50fa4e2394ce06b081334 (diff)
Allow escaping , and } with # in #{}; GitHub issue 1332.
-rw-r--r--format.c46
-rw-r--r--tmux.112
2 files changed, 39 insertions, 19 deletions
diff --git a/format.c b/format.c
index 8f5ec063..7af09942 100644
--- a/format.c
+++ b/format.c
@@ -837,18 +837,22 @@ found:
return (copy);
}
-/* Skip until comma. */
-static char *
-format_skip(char *s)
+/* Skip until end. */
+static const char *
+format_skip(const char *s, char end)
{
int brackets = 0;
for (; *s != '\0'; s++) {
- if (*s == '{')
+ if (*s == '#' && s[1] == '{')
brackets++;
+ if (*s == '#' && strchr(",#{}", s[1]) != NULL) {
+ s++;
+ continue;
+ }
if (*s == '}')
brackets--;
- if (*s == ',' && brackets == 0)
+ if (*s == end && brackets == 0)
break;
}
if (*s == '\0')
@@ -862,7 +866,7 @@ format_choose(char *s, char **left, char **right)
{
char *cp;
- cp = format_skip(s);
+ cp = (char *)format_skip(s, ',');
if (cp == NULL)
return (-1);
*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;
long limit = 0;
int modifiers = 0, compare = 0, search = 0;
+ int literal = 0;
/* Make a copy of the key. */
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? */
switch (copy[0]) {
+ case 'l':
+ if (copy[1] != ':')
+ break;
+ literal = 1;
+ copy += 2;
+ break;
case 'm':
if (copy[1] != ':')
break;
@@ -988,6 +999,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
break;
}
+ /* Is this a literal string? */
+ if (literal) {
+ value = xstrdup(copy);
+ goto done;
+ }
+
/* Is this a comparison or a conditional? */
if (search) {
/* Search in pane. */
@@ -1019,7 +1036,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
free(left);
} else if (*copy == '?') {
/* Conditional: check first and choose second or third. */
- ptr = format_skip(copy);
+ ptr = (char *)format_skip(copy, ',');
if (ptr == NULL)
goto fail;
*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. */
+done:
valuelen = strlen(value);
while (*len - *off < valuelen + 1) {
*buf = xreallocarray(*buf, 2, *len);
@@ -1179,14 +1197,8 @@ format_expand(struct format_tree *ft, const char *fmt)
fmt += n + 1;
continue;
case '{':
- brackets = 1;
- for (ptr = fmt; *ptr != '\0'; ptr++) {
- if (*ptr == '{')
- brackets++;
- if (*ptr == '}' && --brackets == 0)
- break;
- }
- if (*ptr != '}' || brackets != 0)
+ ptr = format_skip(fmt - 2, '}');
+ if (ptr == NULL)
break;
n = ptr - fmt;
@@ -1194,12 +1206,14 @@ format_expand(struct format_tree *ft, const char *fmt)
break;
fmt += n + 1;
continue;
+ case '}':
case '#':
+ case ',':
while (len - off < 2) {
buf = xreallocarray(buf, 2, len);
len *= 2;
}
- buf[off++] = '#';
+ buf[off++] = ch;
continue;
default:
s = NULL;
diff --git a/tmux.1 b/tmux.1
index 87ab94a0..ee50a9fa 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3542,11 +3542,17 @@ The possible variables are listed in the table below, or the name of a
.Nm
option may be used for an option's value.
Some variables have a shorter alias such as
-.Ql #S ,
-and
+.Ql #S ;
.Ql ##
is replaced by a single
-.Ql # .
+.Ql # ,
+.Ql #,
+by a
+.Ql \&,
+and
+.Ql #}
+by a
+.Ql } .
.Pp
Conditionals are available by prefixing with
.Ql \&?