mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +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);
|
server_client_clear_overlay(c);
|
||||||
|
|
||||||
if (fs != NULL)
|
if (fs != NULL) {
|
||||||
ft = format_create_from_state(NULL, c, fs);
|
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);
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
cmd_find_clear_state(&c->prompt_state, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (input == NULL)
|
if (input == NULL)
|
||||||
input = "";
|
input = "";
|
||||||
@@ -701,7 +704,6 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
status_push_screen(c);
|
status_push_screen(c);
|
||||||
|
|
||||||
c->prompt_formats = ft;
|
|
||||||
c->prompt_string = xstrdup (msg);
|
c->prompt_string = xstrdup (msg);
|
||||||
|
|
||||||
if (flags & PROMPT_NOFORMAT)
|
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))
|
if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
|
||||||
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
|
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
|
||||||
|
format_free(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove status line prompt. */
|
/* Remove status line prompt. */
|
||||||
@@ -752,9 +755,6 @@ status_prompt_clear(struct client *c)
|
|||||||
free(c->prompt_last);
|
free(c->prompt_last);
|
||||||
c->prompt_last = NULL;
|
c->prompt_last = NULL;
|
||||||
|
|
||||||
format_free(c->prompt_formats);
|
|
||||||
c->prompt_formats = NULL;
|
|
||||||
|
|
||||||
free(c->prompt_string);
|
free(c->prompt_string);
|
||||||
c->prompt_string = NULL;
|
c->prompt_string = NULL;
|
||||||
|
|
||||||
@@ -774,13 +774,19 @@ status_prompt_clear(struct client *c)
|
|||||||
void
|
void
|
||||||
status_prompt_update(struct client *c, const char *msg, const char *input)
|
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);
|
free(c->prompt_string);
|
||||||
c->prompt_string = xstrdup(msg);
|
c->prompt_string = xstrdup(msg);
|
||||||
|
|
||||||
free(c->prompt_buffer);
|
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_buffer = utf8_fromcstr(tmp);
|
||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
free(tmp);
|
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);
|
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
||||||
|
|
||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
format_free(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
|
/* 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 status_line *sl = &c->status;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
|
struct options *oo = s->options;
|
||||||
struct screen old_screen;
|
struct screen old_screen;
|
||||||
u_int i, lines, offset, left, start, width, n;
|
u_int i, lines, offset, left, start, width, n;
|
||||||
u_int pcursor, pwidth, promptline;
|
u_int pcursor, pwidth, promptline;
|
||||||
u_int ax, aw;
|
u_int ax, aw;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
|
struct format_tree *ft;
|
||||||
const char *msgfmt;
|
const char *msgfmt;
|
||||||
char *expanded, *prompt, *tmp;
|
char *expanded, *prompt, *tmp;
|
||||||
|
|
||||||
@@ -863,12 +872,17 @@ status_prompt_redraw(struct client *c)
|
|||||||
lines = 1;
|
lines = 1;
|
||||||
screen_init(sl->active, c->tty.sx, lines, 0);
|
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");
|
n = options_get_number(s->options, "prompt-cursor-colour");
|
||||||
sl->active->default_ccolour = n;
|
sl->active->default_ccolour = n;
|
||||||
if (c->prompt_mode == PROMPT_COMMAND)
|
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
|
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,
|
screen_set_cursor_style(n, &sl->active->default_cstyle,
|
||||||
&sl->active->default_mode);
|
&sl->active->default_mode);
|
||||||
|
|
||||||
@@ -877,28 +891,29 @@ status_prompt_redraw(struct client *c)
|
|||||||
promptline = lines - 1;
|
promptline = lines - 1;
|
||||||
|
|
||||||
if (c->prompt_mode == PROMPT_COMMAND)
|
if (c->prompt_mode == PROMPT_COMMAND)
|
||||||
style_apply(&gc, s->options, "message-command-style", NULL);
|
style_apply(&gc, oo, "message-command-style", NULL);
|
||||||
else
|
else
|
||||||
style_apply(&gc, s->options, "message-style", NULL);
|
style_apply(&gc, oo, "message-style", NULL);
|
||||||
|
|
||||||
status_prompt_area(c, &ax, &aw);
|
status_prompt_area(c, &ax, &aw);
|
||||||
|
|
||||||
tmp = utf8_tocstr(c->prompt_buffer);
|
tmp = utf8_tocstr(c->prompt_buffer);
|
||||||
format_add(c->prompt_formats, "prompt-input", "%s", tmp);
|
format_add(ft, "prompt-input", "%s", tmp);
|
||||||
prompt = format_expand_time(c->prompt_formats, c->prompt_string);
|
prompt = format_expand_time(ft, c->prompt_string);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set #{message} to the prompt string and expand message-format.
|
* Set #{message} to the prompt string and expand message-format.
|
||||||
* format_draw handles fill, alignment, and decorations in one call.
|
* format_draw handles fill, alignment, and decorations in one call.
|
||||||
*/
|
*/
|
||||||
format_add(c->prompt_formats, "message", "%s", prompt);
|
format_add(ft, "message", "%s", prompt);
|
||||||
format_add(c->prompt_formats, "command_prompt", "%d",
|
format_add(ft, "command_prompt", "%d",
|
||||||
c->prompt_mode == PROMPT_COMMAND);
|
c->prompt_mode == PROMPT_COMMAND);
|
||||||
msgfmt = options_get_string(s->options, "message-format");
|
msgfmt = options_get_string(oo, "message-format");
|
||||||
expanded = format_expand_time(c->prompt_formats, msgfmt);
|
expanded = format_expand_time(ft, msgfmt);
|
||||||
|
free(prompt);
|
||||||
|
|
||||||
start = format_width(prompt);
|
start = format_width(expanded);
|
||||||
if (start > aw)
|
if (start > aw)
|
||||||
start = aw;
|
start = aw;
|
||||||
|
|
||||||
|
|||||||
2
tmux.h
2
tmux.h
@@ -2094,8 +2094,8 @@ struct client {
|
|||||||
struct event message_timer;
|
struct event message_timer;
|
||||||
|
|
||||||
char *prompt_string;
|
char *prompt_string;
|
||||||
struct format_tree *prompt_formats;
|
|
||||||
struct utf8_data *prompt_buffer;
|
struct utf8_data *prompt_buffer;
|
||||||
|
struct cmd_find_state prompt_state;
|
||||||
char *prompt_last;
|
char *prompt_last;
|
||||||
size_t prompt_index;
|
size_t prompt_index;
|
||||||
prompt_input_cb prompt_inputcb;
|
prompt_input_cb prompt_inputcb;
|
||||||
|
|||||||
Reference in New Issue
Block a user