diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index e5c2b12c..c5f958cd 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -42,8 +42,8 @@ const struct cmd_entry cmd_command_prompt_entry = { .name = "command-prompt", .alias = NULL, - .args = { "1beFiklI:Np:t:T:", 0, 1, cmd_command_prompt_args_parse }, - .usage = "[-1beFiklN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE + .args = { "1CbeFiklI:Np:t:T:", 0, 1, cmd_command_prompt_args_parse }, + .usage = "[-1CbeFiklN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [-T prompt-type] [template]", .flags = CMD_CLIENT_TFLAG, @@ -165,6 +165,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) cdata->flags |= PROMPT_KEY; else if (args_has(args, 'e')) cdata->flags |= PROMPT_BSPACE_EXIT; + if (args_has(args, 'C')) + cdata->flags |= PROMPT_NOFREEZE; status_prompt_set(tc, target, cdata->prompts[0].prompt, cdata->prompts[0].input, cmd_command_prompt_callback, cmd_command_prompt_free, cdata, cdata->flags, cdata->prompt_type); diff --git a/control-notify.c b/control-notify.c index ba6a8355..0ced0c87 100644 --- a/control-notify.c +++ b/control-notify.c @@ -24,7 +24,8 @@ #include "tmux.h" #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \ - ((c) != NULL && ((c)->flags & CLIENT_CONTROL)) + ((c) != NULL && ((c)->flags & CLIENT_CONTROL) && \ + (c)->control_state != NULL) void control_notify_pane_mode_changed(int pane) diff --git a/control.c b/control.c index 0273227f..2fc97b5e 100644 --- a/control.c +++ b/control.c @@ -828,6 +828,9 @@ control_stop(struct client *c) struct control_block *cb, *cb1; struct control_sub *csub, *csub1; + if (cs == NULL) + return; + if (~c->flags & CLIENT_CONTROLCONTROL) bufferevent_free(cs->write_event); bufferevent_free(cs->read_event); @@ -841,6 +844,7 @@ control_stop(struct client *c) control_free_block(cs, cb); control_reset_offsets(c); + c->control_state = NULL; free(cs); } diff --git a/format.c b/format.c index 5b7ed129..74399665 100644 --- a/format.c +++ b/format.c @@ -90,6 +90,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) /* Maimum repeat size. */ #define FORMAT_MAX_REPEAT 10000 +/* Maimum precision. */ +#define FORMAT_MAX_PRECISION 100 + /* Format modifiers. */ #define FORMAT_TIMESTRING 0x1 #define FORMAT_BASENAME 0x2 @@ -4886,7 +4889,8 @@ format_replace_expression(struct format_modifier *mexp, /* The third argument may be precision. */ if (argc >= 3) { - prec = strtonum(mexp->argv[2], INT_MIN + 1, INT_MAX, &errstr); + prec = strtonum(mexp->argv[2], -FORMAT_MAX_PRECISION, + FORMAT_MAX_PRECISION, &errstr); if (errstr != NULL) { format_log(es, "expression precision %s: %s", errstr, mexp->argv[2]); @@ -5079,8 +5083,10 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, if (strchr(fm->argv[0], 'p') != NULL) modifiers |= FORMAT_PRETTY; else if (fm->argc >= 2 && - strchr(fm->argv[0], 'f') != NULL) + strchr(fm->argv[0], 'f') != NULL) { + free(time_format); time_format = format_strip(fm->argv[1]); + } break; case 'q': if (fm->argc < 1) diff --git a/key-bindings.c b/key-bindings.c index 3ccb7475..4bb7d801 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -29,7 +29,8 @@ " 'Previous' 'p' {switch-client -p}" \ " ''" \ " 'Renumber' 'N' {move-window -r}" \ - " 'Rename' 'n' {command-prompt -I \"#S\" {rename-session -- '%%'}}" \ + " 'Rename' 'r' {command-prompt -I \"#S\" {rename-session -- '%%'}}" \ + " 'Detach' 'd' {detach-client}" \ " ''" \ " 'New Session' 's' {new-session}" \ " 'New Window' 'w' {new-window}" diff --git a/notify.c b/notify.c index d42e2b9d..8605601c 100644 --- a/notify.c +++ b/notify.c @@ -208,8 +208,12 @@ notify_add(const char *name, struct cmd_find_state *fs, struct client *c, format_add(ne->formats, "hook_window", "@%u", w->id); format_add(ne->formats, "hook_window_name", "%s", w->name); } - if (wp != NULL) + if (wp != NULL) { format_add(ne->formats, "hook_pane", "%%%d", wp->id); + format_add(ne->formats, "hook_window", "@%u", wp->window->id); + format_add(ne->formats, "hook_window_name", "%s", + wp->window->name); + } format_log_debug(ne->formats, __func__); if (c != NULL) diff --git a/options-table.c b/options-table.c index 34bffcdd..aefd2db9 100644 --- a/options-table.c +++ b/options-table.c @@ -414,10 +414,10 @@ const struct options_table_entry options_table[] = { .choices = options_table_get_clipboard_list, .default_num = 1, .text = "When an application requests the clipboard, whether to " - "ignore the request ('off'); respond with the newest buffer " - "('buffer'); request the clipboard from the most recently " - "used terminal ('request'); or to request the clipboard, " - "create a buffer, and send it to the application ('both')." + "ignore the request ('off'); respond with the newest buffer " + "('buffer'); request the clipboard from the most recently " + "used terminal ('request'); or to request the clipboard, " + "create a buffer, and send it to the application ('both')." }, { .name = "history-file", @@ -1024,7 +1024,8 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SESSION, .flags = OPTIONS_TABLE_IS_ARRAY, .default_str = "DISPLAY KRB5CCNAME MSYSTEM SSH_ASKPASS SSH_AUTH_SOCK " - "SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY", + "SSH_AGENT_PID SSH_CONNECTION WAYLAND_DISPLAY " + "WINDOWID XAUTHORITY", .text = "List of environment variables to update in the session " "environment when a client is attached." }, diff --git a/popup.c b/popup.c index bed2b947..2092e185 100644 --- a/popup.c +++ b/popup.c @@ -103,6 +103,27 @@ static const struct menu_item popup_internal_menu_items[] = { { NULL, KEYC_NONE, NULL } }; +static void +popup_free(struct popup_data *pd) +{ + server_client_unref(pd->c); + + if (pd->job != NULL) + job_free(pd->job); + input_free(pd->ictx); + + free(pd->or[0].ranges); + free(pd->or[1].ranges); + free(pd->r.ranges); + screen_free(&pd->s); + colour_palette_free(&pd->palette); + + free(pd->title); + free(pd->style); + free(pd->border_style); + free(pd); +} + static void popup_reapply_styles(struct popup_data *pd) { @@ -343,22 +364,8 @@ popup_free_cb(struct client *c, void *data) cmdq_get_client(item)->retval = pd->status; cmdq_continue(item); } - server_client_unref(pd->c); - if (pd->job != NULL) - job_free(pd->job); - input_free(pd->ictx); - - free(pd->or[0].ranges); - free(pd->or[1].ranges); - free(pd->r.ranges); - screen_free(&pd->s); - colour_palette_free(&pd->palette); - - free(pd->title); - free(pd->style); - free(pd->border_style); - free(pd); + popup_free(pd); } static void @@ -857,6 +864,10 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px, pd->job = job_run(shellcmd, argc, argv, env, s, cwd, popup_job_update_cb, popup_job_complete_cb, NULL, pd, JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy); + if (pd->job == NULL) { + popup_free(pd); + return (-1); + } pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette, c); } diff --git a/regress/input-keys.sh b/regress/input-keys.sh index d3b90995..96d2d5e8 100644 --- a/regress/input-keys.sh +++ b/regress/input-keys.sh @@ -7,9 +7,10 @@ TERM=screen TMUX="$TEST_TMUX -Ltest" $TMUX kill-server 2>/dev/null sleep 1 -$TMUX -f/dev/null new -x20 -y2 -d || exit 1 +$TMUX -f/dev/null new -x20 -y2 -d \; set -g escape-time 0 || exit 1 +sleep 1 +W=$($TMUX new-window -P -- sh -c 'stty raw -echo && cat -tv') sleep 1 -$TMUX set -g escape-time 0 exit_status=0 @@ -17,14 +18,13 @@ assert_key () { key=$1 expected_code=$2 - W=$($TMUX new-window -P -- sh -c 'stty raw -echo && cat -tv') - $TMUX send-keys -t$W "$key" 'EOL' || exit 1 - sleep 0.2 + $TMUX send-keys -t$W -R \; \ + clear-history -t$W \; \ + send-keys -t$W "$key" 'EOL' || exit 1 actual_code=$($TMUX capturep -pt$W | \ head -1 | \ sed -e 's/EOL.*$//') - $TMUX kill-window -t$W || exit 1 if [ "$actual_code" = "$expected_code" ]; then if [ -n "$VERBOSE" ]; then diff --git a/status.c b/status.c index c39d0d8f..5ecf7bf9 100644 --- a/status.c +++ b/status.c @@ -728,7 +728,7 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs, c->prompt_type = prompt_type; c->prompt_mode = PROMPT_ENTRY; - if (~flags & PROMPT_INCREMENTAL) + if ((~flags & PROMPT_INCREMENTAL) && (~flags & PROMPT_NOFREEZE)) c->tty.flags |= TTY_FREEZE; c->flags |= CLIENT_REDRAWSTATUS; diff --git a/tmux.1 b/tmux.1 index c3f0d9b2..fe874a1c 100644 --- a/tmux.1 +++ b/tmux.1 @@ -7126,7 +7126,7 @@ See for possible values for .Ar prompt\-type . .It Xo Ic command\-prompt -.Op Fl 1beFiklN +.Op Fl 1bCeFiklN .Op Fl I Ar inputs .Op Fl p Ar prompts .Op Fl t Ar target\-client @@ -7196,6 +7196,9 @@ is like but the key press is translated to a key name. .Fl N makes the prompt only accept numeric key presses. +If +.Fl C +given, panes will continue to be updated while the prompt is displayed. .Fl i executes the command every time the prompt input changes instead of when the user exits the command prompt. diff --git a/tmux.h b/tmux.h index b2a7016f..08d6d305 100644 --- a/tmux.h +++ b/tmux.h @@ -2165,6 +2165,7 @@ struct client { #define PROMPT_ACCEPT 0x20 #define PROMPT_QUOTENEXT 0x40 #define PROMPT_BSPACE_EXIT 0x80 +#define PROMPT_NOFREEZE 0x100 int prompt_flags; enum prompt_type prompt_type; int prompt_cursor;