Set return code for confirm-before and make command-prompt also block,

GitHub issue 2822.
This commit is contained in:
nicm 2021-08-13 06:50:42 +00:00
parent e2f6f58fe5
commit a2b8506917
5 changed files with 58 additions and 35 deletions

View File

@ -40,8 +40,8 @@ const struct cmd_entry cmd_command_prompt_entry = {
.name = "command-prompt",
.alias = NULL,
.args = { "1FkiI:Np:t:T:", 0, 1 },
.usage = "[-1FkiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE
.args = { "1bFkiI:Np:t:T:", 0, 1 },
.usage = "[-1bFkiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE
" [-T type] [template]",
.flags = CMD_CLIENT_TFLAG,
@ -49,17 +49,20 @@ const struct cmd_entry cmd_command_prompt_entry = {
};
struct cmd_command_prompt_cdata {
int flags;
enum prompt_type prompt_type;
struct cmdq_item *item;
struct cmd_parse_input pi;
char *inputs;
char *next_input;
int flags;
enum prompt_type prompt_type;
char *prompts;
char *next_prompt;
char *inputs;
char *next_input;
char *template;
int idx;
char *prompts;
char *next_prompt;
char *template;
int idx;
};
static enum cmd_retval
@ -72,21 +75,23 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
struct cmd_command_prompt_cdata *cdata;
char *prompt, *ptr, *input = NULL;
size_t n;
int wait = !args_has(args, 'b');
if (tc->prompt_string != NULL)
return (CMD_RETURN_NORMAL);
cdata = xcalloc(1, sizeof *cdata);
cdata->inputs = NULL;
cdata->next_input = NULL;
cdata->prompts = NULL;
cdata->next_prompt = NULL;
cdata->template = NULL;
cdata->idx = 1;
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;
if (args->argc != 0 && args_has(args, 'F'))
cdata->template = format_single_from_target(item, args->argv[0]);
else if (args->argc != 0)
@ -140,7 +145,9 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
cdata->flags, cdata->prompt_type);
free(prompt);
return (CMD_RETURN_NORMAL);
if (!wait)
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
}
static int
@ -150,12 +157,13 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s,
struct cmd_command_prompt_cdata *cdata = data;
char *new_template, *prompt, *ptr, *error;
char *input = NULL;
struct cmdq_item *item = cdata->item;
enum cmd_parse_status status;
if (s == NULL)
return (0);
goto out;
if (done && (cdata->flags & PROMPT_INCREMENTAL))
return (0);
goto out;
new_template = cmd_template_replace(cdata->template, s, cdata->idx);
if (done) {
@ -177,7 +185,13 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s,
return (1);
}
status = cmd_parse_and_append(new_template, NULL, c, NULL, &error);
if (item != NULL) {
status = cmd_parse_and_insert(new_template, &cdata->pi, item,
cmdq_get_state(item), &error);
} else {
status = cmd_parse_and_append(new_template, &cdata->pi, c, NULL,
&error);
}
if (status == CMD_PARSE_ERROR) {
cmdq_append(c, cmdq_get_error(error));
free(error);
@ -187,6 +201,10 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s,
free(new_template);
if (c->prompt_inputcb != cmd_command_prompt_callback)
return (1);
out:
if (item != NULL)
cmdq_continue(item);
return (0);
}

View File

@ -75,7 +75,6 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
cdata = xmalloc(sizeof *cdata);
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;
@ -88,8 +87,8 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
status_prompt_set(tc, target, new_prompt, NULL,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE, PROMPT_TYPE_COMMAND);
free(new_prompt);
if (!wait)
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
@ -104,14 +103,16 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s,
char *error;
struct cmdq_item *item = cdata->item;
enum cmd_parse_status status;
int retcode = 1;
if (c->flags & CLIENT_DEAD)
return (0);
goto out;
if (s == NULL || *s == '\0')
goto out;
if (tolower((u_char)s[0]) != 'y' || s[1] != '\0')
goto out;
retcode = 0;
if (item != NULL) {
status = cmd_parse_and_insert(cmd, &cdata->pi, item,
@ -124,8 +125,12 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s,
}
out:
if (item != NULL)
cmdq_continue(item);
if (item != NULL) {
if (cmdq_get_client(item) != NULL &&
cmdq_get_client(item)->session == NULL)
cmdq_get_client(item)->retval = retcode;
cmdq_continue(item);
}
return (0);
}

View File

@ -104,8 +104,6 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
cdata->cmd_if = xstrdup(args->argv[1]);
if (args->argc == 3)
cdata->cmd_else = xstrdup(args->argv[2]);
else
cdata->cmd_else = NULL;
if (!args_has(args, 'b'))
cdata->client = cmdq_get_client(item);
@ -116,10 +114,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
if (!args_has(args, 'b'))
cdata->item = item;
else
cdata->item = NULL;
memset(&cdata->input, 0, sizeof cdata->input);
cmd_get_source(self, &file, &cdata->input.line);
if (file != NULL)
cdata->input.file = xstrdup(file);

View File

@ -121,7 +121,6 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
cdata->shell = !args_has(args, 'C');
if (!cdata->shell) {
memset(&cdata->pi, 0, sizeof cdata->pi);
cmd_get_source(self, &cdata->pi.file, &cdata->pi.line);
if (wait)
cdata->pi.item = item;

10
tmux.1
View File

@ -5414,7 +5414,7 @@ See
for possible values for
.Ar prompt-type .
.It Xo Ic command-prompt
.Op Fl 1FikN
.Op Fl 1bFikN
.Op Fl I Ar inputs
.Op Fl p Ar prompts
.Op Fl t Ar target-client
@ -5516,7 +5516,12 @@ option:
.It Li "Move cursor to previous word" Ta "b" Ta "M-b"
.It Li "Move cursor to start" Ta "0" Ta "C-a"
.It Li "Transpose characters" Ta "" Ta "C-t"
.Pp
.El
With
.Fl b ,
the prompt is shown in the background and the invoking client does not exit
until it is dismissed.
.It Xo Ic confirm-before
.Op Fl b
.Op Fl p Ar prompt
@ -5537,7 +5542,8 @@ It may contain the special character sequences supported by the
option.
With
.Fl b ,
the prompt is shown in the background and the client.
the prompt is shown in the background and the invoking client does not exit
until it is dismissed.
.It Xo Ic display-menu
.Op Fl O
.Op Fl c Ar target-client