mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								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':
 | 
			
		||||
				if (fm->argc < 1)
 | 
			
		||||
					modifiers |= FORMAT_QUOTE;
 | 
			
		||||
				else if (strchr(fm->argv[0], 'e') != NULL)
 | 
			
		||||
					modifiers |= FORMAT_ESCAPE;
 | 
			
		||||
				break;
 | 
			
		||||
			case 'E':
 | 
			
		||||
				modifiers |= FORMAT_EXPAND;
 | 
			
		||||
 
 | 
			
		||||
@@ -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."
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user