Make confirm-before optionally block the invoking client like run-shell,

GitHub issue 2819.
pull/2824/head
nicm 2021-08-11 08:40:58 +00:00
parent f6755c6f2c
commit 338ec859a4
2 changed files with 35 additions and 10 deletions

View File

@ -39,15 +39,17 @@ const struct cmd_entry cmd_confirm_before_entry = {
.name = "confirm-before", .name = "confirm-before",
.alias = "confirm", .alias = "confirm",
.args = { "p:t:", 1, 1 }, .args = { "bp:t:", 1, 1 },
.usage = "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command", .usage = "[-b] [-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
.flags = CMD_CLIENT_TFLAG, .flags = CMD_CLIENT_TFLAG,
.exec = cmd_confirm_before_exec .exec = cmd_confirm_before_exec
}; };
struct cmd_confirm_before_data { struct cmd_confirm_before_data {
char *cmd; char *cmd;
struct cmdq_item *item;
struct cmd_parse_input pi;
}; };
static enum cmd_retval static enum cmd_retval
@ -59,6 +61,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
struct cmd_find_state *target = cmdq_get_target(item); struct cmd_find_state *target = cmdq_get_target(item);
char *cmd, *copy, *new_prompt, *ptr; char *cmd, *copy, *new_prompt, *ptr;
const char *prompt; const char *prompt;
int wait = !args_has(args, 'b');
if ((prompt = args_get(args, 'p')) != NULL) if ((prompt = args_get(args, 'p')) != NULL)
xasprintf(&new_prompt, "%s ", prompt); xasprintf(&new_prompt, "%s ", prompt);
@ -72,12 +75,24 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]); cdata->cmd = xstrdup(args->argv[0]);
memset(&cdata->pi, 0, sizeof cdata->pi);
cmd_get_source(self, &cdata->pi.file, &cdata->pi.line);
if (wait)
cdata->pi.item = item;
cdata->pi.c = tc;
cmd_find_copy_state(&cdata->pi.fs, target);
if (wait)
cdata->item = item;
status_prompt_set(tc, target, new_prompt, NULL, status_prompt_set(tc, target, new_prompt, NULL,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata, cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE, PROMPT_TYPE_COMMAND); PROMPT_SINGLE, PROMPT_TYPE_COMMAND);
free(new_prompt); free(new_prompt);
return (CMD_RETURN_NORMAL); if (!wait)
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
} }
static int static int
@ -85,23 +100,32 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s,
__unused int done) __unused int done)
{ {
struct cmd_confirm_before_data *cdata = data; struct cmd_confirm_before_data *cdata = data;
const char *cmd = cdata->cmd;
char *error; char *error;
struct cmdq_item *item = cdata->item;
enum cmd_parse_status status; enum cmd_parse_status status;
if (c->flags & CLIENT_DEAD) if (c->flags & CLIENT_DEAD)
return (0); return (0);
if (s == NULL || *s == '\0') if (s == NULL || *s == '\0')
return (0); goto out;
if (tolower((u_char)s[0]) != 'y' || s[1] != '\0') if (tolower((u_char)s[0]) != 'y' || s[1] != '\0')
return (0); goto out;
status = cmd_parse_and_append(cdata->cmd, NULL, c, NULL, &error); if (item != NULL) {
status = cmd_parse_and_insert(cmd, &cdata->pi, item,
cmdq_get_state(item), &error);
} else
status = cmd_parse_and_append(cmd, &cdata->pi, c, NULL, &error);
if (status == CMD_PARSE_ERROR) { if (status == CMD_PARSE_ERROR) {
cmdq_append(c, cmdq_get_error(error)); cmdq_append(c, cmdq_get_error(error));
free(error); free(error);
} }
out:
if (item != NULL)
cmdq_continue(item);
return (0); return (0);
} }

7
tmux.1
View File

@ -5507,6 +5507,7 @@ option:
.It Li "Transpose characters" Ta "" Ta "C-t" .It Li "Transpose characters" Ta "" Ta "C-t"
.El .El
.It Xo Ic confirm-before .It Xo Ic confirm-before
.Op Fl b
.Op Fl p Ar prompt .Op Fl p Ar prompt
.Op Fl t Ar target-client .Op Fl t Ar target-client
.Ar command .Ar command
@ -5523,9 +5524,9 @@ is the prompt to display; otherwise a prompt is constructed from
It may contain the special character sequences supported by the It may contain the special character sequences supported by the
.Ic status-left .Ic status-left
option. option.
.Pp With
This command works only from inside .Fl b ,
.Nm . the prompt is shown in the background and the client.
.It Xo Ic display-menu .It Xo Ic display-menu
.Op Fl O .Op Fl O
.Op Fl c Ar target-client .Op Fl c Ar target-client