From 9a74bba007a60b93d1fdf68772e5cfb61b3558ff Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Dec 2020 08:12:58 +0000 Subject: [PATCH] Make replacement of ##s consistent when drawing formats, whether followed by [ or not. Add a flag (e) to the q: format modifier to double up #s and use it for the window_flags format variable so it doesn't end up escaping any following text. GitHub issue 2485. --- format-draw.c | 8 ++++++-- format.c | 32 +++++++++++++++++++++++++++++--- options-table.c | 4 ++-- tmux.1 | 7 ++++++- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/format-draw.c b/format-draw.c index e73c5df4..67b961d9 100644 --- a/format-draw.c +++ b/format-draw.c @@ -563,13 +563,17 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base, if (cp[0] == '#' && cp[1] != '[' && cp[1] != '\0') { for (n = 1; cp[n] == '#'; n++) /* nothing */; + even = ((n % 2) == 0); if (cp[n] != '[') { - width[current] += n; cp += n; + if (even) + n = (n / 2); + else + n = (n / 2) + 1; + width[current] += n; format_draw_many(&ctx[current], &sy, '#', n); continue; } - even = ((n % 2) == 0); if (even) cp += (n + 1); else diff --git a/format.c b/format.c index 91955259..98dc4cb7 100644 --- a/format.c +++ b/format.c @@ -99,6 +99,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_PRETTY 0x400 #define FORMAT_LENGTH 0x800 #define FORMAT_WIDTH 0x1000 +#define FORMAT_ESCAPE 0x2000 /* Limit on recursion. */ #define FORMAT_LOOP_LIMIT 10 @@ -1394,6 +1395,23 @@ format_quote(const char *s) return (out); } +/* Escape #s in string. */ +static char * +format_escape(const char *s) +{ + const char *cp; + char *out, *at; + + at = out = xmalloc(strlen(s) * 2 + 1); + for (cp = s; *cp != '\0'; cp++) { + if (*cp == '#') + *at++ = '#'; + *at++ = *cp; + } + *at = '\0'; + return (out); +} + /* Make a prettier time. */ static char * format_pretty_time(time_t t) @@ -1539,6 +1557,11 @@ found: found = xstrdup(format_quote(saved)); free(saved); } + if (modifiers & FORMAT_ESCAPE) { + saved = found; + found = xstrdup(format_escape(saved)); + free(saved); + } return (found); } @@ -1689,7 +1712,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, cp++; /* Check single character modifiers with no arguments. */ - if (strchr("lbdnqwETSWP<>", cp[0]) != NULL && + if (strchr("lbdnwETSWP<>", cp[0]) != NULL && format_is_end(cp[1])) { format_add_modifier(&list, count, cp, 1, NULL, 0); cp++; @@ -1710,7 +1733,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, } /* Now try single character with arguments. */ - if (strchr("mCst=pe", cp[0]) == NULL) + if (strchr("mCst=peq", cp[0]) == NULL) break; c = cp[0]; @@ -2216,7 +2239,10 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, time_format = format_strip(fm->argv[1]); break; case 'q': - modifiers |= FORMAT_QUOTE; + if (fm->argc < 1) + modifiers |= FORMAT_QUOTE; + else if (strchr(fm->argv[0], 'e') != NULL) + modifiers |= FORMAT_ESCAPE; break; case 'E': modifiers |= FORMAT_EXPAND; diff --git a/options-table.c b/options-table.c index 2ae49d7a..56e1c895 100644 --- a/options-table.c +++ b/options-table.c @@ -1014,7 +1014,7 @@ const struct options_table_entry options_table[] = { { .name = "window-status-current-format", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, - .default_str = "#I:#W#{?window_flags,#{window_flags}, }", + .default_str = "#I:#W#{?window_flags,#{q/e:window_flags}, }", .text = "Format of the current window in the status line." }, @@ -1030,7 +1030,7 @@ const struct options_table_entry options_table[] = { { .name = "window-status-format", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, - .default_str = "#I:#W#{?window_flags,#{window_flags}, }", + .default_str = "#I:#W#{?window_flags,#{q/e:window_flags}, }", .text = "Format of windows in the status line, except the current " "window." }, diff --git a/tmux.1 b/tmux.1 index b3a74b0a..9d1021f3 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4638,7 +4638,12 @@ of the variable respectively. .Ql q:\& will escape .Xr sh 1 -special characters. +special characters or with an +.Ql e +suffix, escape hash characters (so +.Ql # +becomes +.Ql ## ). .Ql E:\& will expand the format twice, for example .Ql #{E:status-left}