mirror of
https://github.com/tmux/tmux.git
synced 2026-05-08 14:52:17 +00:00
Do not cache format for status line because it stores various pointers
that might be stale, instead cache the cmd_find_state and rebuild the formats every time they are needed. Reported by Marcel Partap in GitHub isue 5065.
This commit is contained in:
53
status.c
53
status.c
@@ -689,10 +689,13 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
||||
|
||||
server_client_clear_overlay(c);
|
||||
|
||||
if (fs != NULL)
|
||||
if (fs != NULL) {
|
||||
ft = format_create_from_state(NULL, c, fs);
|
||||
else
|
||||
cmd_find_copy_state(&c->prompt_state, fs);
|
||||
} else {
|
||||
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||
cmd_find_clear_state(&c->prompt_state, 0);
|
||||
}
|
||||
|
||||
if (input == NULL)
|
||||
input = "";
|
||||
@@ -701,7 +704,6 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
||||
status_prompt_clear(c);
|
||||
status_push_screen(c);
|
||||
|
||||
c->prompt_formats = ft;
|
||||
c->prompt_string = xstrdup (msg);
|
||||
|
||||
if (flags & PROMPT_NOFORMAT)
|
||||
@@ -737,6 +739,7 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
||||
|
||||
if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
|
||||
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
|
||||
format_free(ft);
|
||||
}
|
||||
|
||||
/* Remove status line prompt. */
|
||||
@@ -752,9 +755,6 @@ status_prompt_clear(struct client *c)
|
||||
free(c->prompt_last);
|
||||
c->prompt_last = NULL;
|
||||
|
||||
format_free(c->prompt_formats);
|
||||
c->prompt_formats = NULL;
|
||||
|
||||
free(c->prompt_string);
|
||||
c->prompt_string = NULL;
|
||||
|
||||
@@ -774,13 +774,19 @@ status_prompt_clear(struct client *c)
|
||||
void
|
||||
status_prompt_update(struct client *c, const char *msg, const char *input)
|
||||
{
|
||||
char *tmp;
|
||||
struct format_tree *ft;
|
||||
char *tmp;
|
||||
|
||||
if (cmd_find_valid_state(&c->prompt_state))
|
||||
ft = format_create_from_state(NULL, c, &c->prompt_state);
|
||||
else
|
||||
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||
|
||||
free(c->prompt_string);
|
||||
c->prompt_string = xstrdup(msg);
|
||||
|
||||
free(c->prompt_buffer);
|
||||
tmp = format_expand_time(c->prompt_formats, input);
|
||||
tmp = format_expand_time(ft, input);
|
||||
c->prompt_buffer = utf8_fromcstr(tmp);
|
||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||
free(tmp);
|
||||
@@ -788,6 +794,7 @@ status_prompt_update(struct client *c, const char *msg, const char *input)
|
||||
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
||||
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
format_free(ft);
|
||||
}
|
||||
|
||||
/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
|
||||
@@ -846,11 +853,13 @@ status_prompt_redraw(struct client *c)
|
||||
struct status_line *sl = &c->status;
|
||||
struct screen_write_ctx ctx;
|
||||
struct session *s = c->session;
|
||||
struct options *oo = s->options;
|
||||
struct screen old_screen;
|
||||
u_int i, lines, offset, left, start, width, n;
|
||||
u_int pcursor, pwidth, promptline;
|
||||
u_int ax, aw;
|
||||
struct grid_cell gc;
|
||||
struct format_tree *ft;
|
||||
const char *msgfmt;
|
||||
char *expanded, *prompt, *tmp;
|
||||
|
||||
@@ -863,12 +872,17 @@ status_prompt_redraw(struct client *c)
|
||||
lines = 1;
|
||||
screen_init(sl->active, c->tty.sx, lines, 0);
|
||||
|
||||
if (cmd_find_valid_state(&c->prompt_state))
|
||||
ft = format_create_from_state(NULL, c, &c->prompt_state);
|
||||
else
|
||||
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||
|
||||
n = options_get_number(s->options, "prompt-cursor-colour");
|
||||
sl->active->default_ccolour = n;
|
||||
if (c->prompt_mode == PROMPT_COMMAND)
|
||||
n = options_get_number(s->options, "prompt-command-cursor-style");
|
||||
n = options_get_number(oo, "prompt-command-cursor-style");
|
||||
else
|
||||
n = options_get_number(s->options, "prompt-cursor-style");
|
||||
n = options_get_number(oo, "prompt-cursor-style");
|
||||
screen_set_cursor_style(n, &sl->active->default_cstyle,
|
||||
&sl->active->default_mode);
|
||||
|
||||
@@ -877,28 +891,29 @@ status_prompt_redraw(struct client *c)
|
||||
promptline = lines - 1;
|
||||
|
||||
if (c->prompt_mode == PROMPT_COMMAND)
|
||||
style_apply(&gc, s->options, "message-command-style", NULL);
|
||||
style_apply(&gc, oo, "message-command-style", NULL);
|
||||
else
|
||||
style_apply(&gc, s->options, "message-style", NULL);
|
||||
style_apply(&gc, oo, "message-style", NULL);
|
||||
|
||||
status_prompt_area(c, &ax, &aw);
|
||||
|
||||
tmp = utf8_tocstr(c->prompt_buffer);
|
||||
format_add(c->prompt_formats, "prompt-input", "%s", tmp);
|
||||
prompt = format_expand_time(c->prompt_formats, c->prompt_string);
|
||||
format_add(ft, "prompt-input", "%s", tmp);
|
||||
prompt = format_expand_time(ft, c->prompt_string);
|
||||
free(tmp);
|
||||
|
||||
/*
|
||||
* Set #{message} to the prompt string and expand message-format.
|
||||
* format_draw handles fill, alignment, and decorations in one call.
|
||||
*/
|
||||
format_add(c->prompt_formats, "message", "%s", prompt);
|
||||
format_add(c->prompt_formats, "command_prompt", "%d",
|
||||
format_add(ft, "message", "%s", prompt);
|
||||
format_add(ft, "command_prompt", "%d",
|
||||
c->prompt_mode == PROMPT_COMMAND);
|
||||
msgfmt = options_get_string(s->options, "message-format");
|
||||
expanded = format_expand_time(c->prompt_formats, msgfmt);
|
||||
msgfmt = options_get_string(oo, "message-format");
|
||||
expanded = format_expand_time(ft, msgfmt);
|
||||
free(prompt);
|
||||
|
||||
start = format_width(prompt);
|
||||
start = format_width(expanded);
|
||||
if (start > aw)
|
||||
start = aw;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user