Add q: format prefix to escape sh(1) special characters. Suggested by

someone ages ago and then more recently in GitHub issue 1449.
pull/1398/merge
nicm 2018-08-26 09:28:42 +00:00
parent f38b5a1b58
commit 1b4402c823
2 changed files with 33 additions and 0 deletions

View File

@ -94,6 +94,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_BASENAME 0x2
#define FORMAT_DIRNAME 0x4
#define FORMAT_SUBSTITUTE 0x8
#define FORMAT_QUOTE 0x10
/* Entry in format tree. */
struct format_entry {
@ -754,6 +755,23 @@ format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
fe->value = NULL;
}
/* Quote special characters in string. */
static char *
format_quote(const char *s)
{
const char *cp;
char *out, *at;
at = out = xmalloc(strlen(s) * 2 + 1);
for (cp = s; *cp != '\0'; cp++) {
if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
*at++ = '\\';
*at++ = *cp;
}
*at = '\0';
return (out);
}
/* Find a format entry. */
static char *
format_find(struct format_tree *ft, const char *key, int modifiers)
@ -836,6 +854,11 @@ found:
copy = xstrdup(dirname(saved));
free(saved);
}
if (modifiers & FORMAT_QUOTE) {
saved = copy;
copy = xstrdup(format_quote(saved));
free(saved);
}
return (copy);
}
@ -976,6 +999,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
modifiers |= FORMAT_TIMESTRING;
copy += 2;
break;
case 'q':
if (copy[1] != ':')
break;
modifiers |= FORMAT_QUOTE;
copy += 2;
break;
case 's':
sep = copy[1];
if (sep == ':' || !ispunct((u_char)sep))

4
tmux.1
View File

@ -3676,6 +3676,10 @@ prefixes are
and
.Xr dirname 3
of the variable respectively.
.Ql q:
will escape
.Xr sh 1
special characters.
A prefix of the form
.Ql s/foo/bar/:
will substitute