mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Add s/foo/bar/: prefix for formats to substitute bar for foo.
This commit is contained in:
parent
64571368dc
commit
5a5b950e8b
80
format.c
80
format.c
@ -99,6 +99,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
|||||||
#define FORMAT_TIMESTRING 0x1
|
#define FORMAT_TIMESTRING 0x1
|
||||||
#define FORMAT_BASENAME 0x2
|
#define FORMAT_BASENAME 0x2
|
||||||
#define FORMAT_DIRNAME 0x4
|
#define FORMAT_DIRNAME 0x4
|
||||||
|
#define FORMAT_SUBSTITUTE 0x8
|
||||||
|
|
||||||
/* Entry in format tree. */
|
/* Entry in format tree. */
|
||||||
struct format_entry {
|
struct format_entry {
|
||||||
@ -682,8 +683,9 @@ int
|
|||||||
format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
||||||
char **buf, size_t *len, size_t *off)
|
char **buf, size_t *len, size_t *off)
|
||||||
{
|
{
|
||||||
char *copy, *copy0, *endptr, *ptr, *saved, *trimmed, *value;
|
char *copy, *copy0, *endptr, *ptr, *found, *new, *value;
|
||||||
size_t valuelen;
|
char *from = NULL, *to = NULL;
|
||||||
|
size_t valuelen, newlen, fromlen, tolen, used;
|
||||||
u_long limit = 0;
|
u_long limit = 0;
|
||||||
int modifiers = 0, brackets;
|
int modifiers = 0, brackets;
|
||||||
|
|
||||||
@ -721,6 +723,29 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
modifiers |= FORMAT_TIMESTRING;
|
modifiers |= FORMAT_TIMESTRING;
|
||||||
copy += 2;
|
copy += 2;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
if (copy[1] != '/')
|
||||||
|
break;
|
||||||
|
from = copy + 2;
|
||||||
|
for (copy = from; *copy != '\0' && *copy != '/'; copy++)
|
||||||
|
/* nothing */;
|
||||||
|
if (copy[0] != '/' || copy == from) {
|
||||||
|
copy = copy0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
copy[0] = '\0';
|
||||||
|
to = copy + 1;
|
||||||
|
for (copy = to; *copy != '\0' && *copy != '/'; copy++)
|
||||||
|
/* nothing */;
|
||||||
|
if (copy[0] != '/' || copy[1] != ':') {
|
||||||
|
copy = copy0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
copy[0] = '\0';
|
||||||
|
|
||||||
|
modifiers |= FORMAT_SUBSTITUTE;
|
||||||
|
copy += 2;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -734,7 +759,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
|
|
||||||
value = ptr + 1;
|
value = ptr + 1;
|
||||||
saved = format_find(ft, copy + 1, modifiers);
|
found = format_find(ft, copy + 1, modifiers);
|
||||||
|
|
||||||
brackets = 0;
|
brackets = 0;
|
||||||
for (ptr = ptr + 1; *ptr != '\0'; ptr++) {
|
for (ptr = ptr + 1; *ptr != '\0'; ptr++) {
|
||||||
@ -748,29 +773,56 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
if (*ptr == '\0')
|
if (*ptr == '\0')
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (saved != NULL && *saved != '\0' &&
|
if (found != NULL && *found != '\0' &&
|
||||||
(saved[0] != '0' || saved[1] != '\0')) {
|
(found[0] != '0' || found[1] != '\0')) {
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
} else
|
} else
|
||||||
value = ptr + 1;
|
value = ptr + 1;
|
||||||
value = format_expand(ft, value);
|
value = format_expand(ft, value);
|
||||||
free(saved);
|
free(found);
|
||||||
saved = value;
|
|
||||||
} else {
|
} else {
|
||||||
saved = value = format_find(ft, copy, modifiers);
|
value = format_find(ft, copy, modifiers);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
saved = value = xstrdup("");
|
value = xstrdup("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform substitution if any. */
|
||||||
|
if (modifiers & FORMAT_SUBSTITUTE) {
|
||||||
|
fromlen = strlen(from);
|
||||||
|
tolen = strlen(to);
|
||||||
|
|
||||||
|
newlen = strlen(value) + 1;
|
||||||
|
copy = new = xmalloc(newlen);
|
||||||
|
for (ptr = value; *ptr != '\0'; /* nothing */) {
|
||||||
|
if (strncmp(ptr, from, fromlen) != 0) {
|
||||||
|
*new++ = *ptr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
used = new - copy;
|
||||||
|
|
||||||
|
newlen += tolen;
|
||||||
|
copy = xrealloc(copy, newlen);
|
||||||
|
|
||||||
|
new = copy + used;
|
||||||
|
memcpy(new, to, tolen);
|
||||||
|
|
||||||
|
new += tolen;
|
||||||
|
ptr += fromlen;
|
||||||
|
}
|
||||||
|
*new = '\0';
|
||||||
|
free(value);
|
||||||
|
value = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Truncate the value if needed. */
|
/* Truncate the value if needed. */
|
||||||
if (limit != 0) {
|
if (limit != 0) {
|
||||||
value = trimmed = utf8_trimcstr(value, limit);
|
new = utf8_trimcstr(value, limit);
|
||||||
free(saved);
|
free(value);
|
||||||
saved = trimmed;
|
value = new;
|
||||||
}
|
}
|
||||||
valuelen = strlen(value);
|
|
||||||
|
|
||||||
/* Expand the buffer and copy in the value. */
|
/* Expand the buffer and copy in the value. */
|
||||||
|
valuelen = strlen(value);
|
||||||
while (*len - *off < valuelen + 1) {
|
while (*len - *off < valuelen + 1) {
|
||||||
*buf = xreallocarray(*buf, 2, *len);
|
*buf = xreallocarray(*buf, 2, *len);
|
||||||
*len *= 2;
|
*len *= 2;
|
||||||
@ -778,7 +830,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
|||||||
memcpy(*buf + *off, value, valuelen);
|
memcpy(*buf + *off, value, valuelen);
|
||||||
*off += valuelen;
|
*off += valuelen;
|
||||||
|
|
||||||
free(saved);
|
free(value);
|
||||||
free(copy0);
|
free(copy0);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
7
tmux.1
7
tmux.1
@ -3311,6 +3311,13 @@ prefixes are
|
|||||||
and
|
and
|
||||||
.Xr dirname 3
|
.Xr dirname 3
|
||||||
of the variable respectively.
|
of the variable respectively.
|
||||||
|
A prefix of the form
|
||||||
|
.Ql s/foo/bar/:
|
||||||
|
will substitute
|
||||||
|
.Ql foo
|
||||||
|
with
|
||||||
|
.Ql bar
|
||||||
|
throughout.
|
||||||
.Pp
|
.Pp
|
||||||
In addition, the first line of a shell command's output may be inserted using
|
In addition, the first line of a shell command's output may be inserted using
|
||||||
.Ql #() .
|
.Ql #() .
|
||||||
|
Loading…
Reference in New Issue
Block a user