version 1.59, 2021/08/21 10:22:38 |
version 1.60, 2021/08/23 12:33:55 |
|
|
.exec = cmd_command_prompt_exec |
.exec = cmd_command_prompt_exec |
}; |
}; |
|
|
|
struct cmd_command_prompt_prompt { |
|
char *input; |
|
char *prompt; |
|
}; |
|
|
struct cmd_command_prompt_cdata { |
struct cmd_command_prompt_cdata { |
struct cmdq_item *item; |
struct cmdq_item *item; |
struct cmd_parse_input pi; |
struct args_command_state *state; |
|
|
int flags; |
int flags; |
enum prompt_type prompt_type; |
enum prompt_type prompt_type; |
|
|
char *inputs; |
struct cmd_command_prompt_prompt *prompts; |
char *next_input; |
u_int count; |
|
u_int current; |
|
|
char *prompts; |
int argc; |
char *next_prompt; |
char **argv; |
|
|
char *template; |
|
int idx; |
|
}; |
}; |
|
|
static enum cmd_retval |
static enum cmd_retval |
|
|
struct args *args = cmd_get_args(self); |
struct args *args = cmd_get_args(self); |
struct client *tc = cmdq_get_target_client(item); |
struct client *tc = cmdq_get_target_client(item); |
struct cmd_find_state *target = cmdq_get_target(item); |
struct cmd_find_state *target = cmdq_get_target(item); |
const char *inputs, *prompts, *type, *s; |
const char *type, *s, *input; |
struct cmd_command_prompt_cdata *cdata; |
struct cmd_command_prompt_cdata *cdata; |
char *prompt, *comma, *input = NULL; |
char *tmp, *prompts, *prompt, *next_prompt; |
|
char *inputs, *next_input; |
u_int count = args_count(args); |
u_int count = args_count(args); |
size_t n; |
int wait = !args_has(args, 'b'), space = 1; |
int wait = !args_has(args, 'b'); |
|
|
|
if (tc->prompt_string != NULL) |
if (tc->prompt_string != NULL) |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
|
|
wait = 0; |
wait = 0; |
|
|
cdata = xcalloc(1, sizeof *cdata); |
cdata = xcalloc(1, sizeof *cdata); |
cdata->idx = 1; |
|
|
|
cmd_get_source(self, &cdata->pi.file, &cdata->pi.line); |
|
if (wait) |
if (wait) |
cdata->pi.item = item; |
|
cdata->pi.c = tc; |
|
cmd_find_copy_state(&cdata->pi.fs, target); |
|
|
|
if (wait) |
|
cdata->item = item; |
cdata->item = item; |
|
cdata->state = args_make_commands_prepare(self, item, 0, "%1", wait, |
|
args_has(args, 'F')); |
|
|
if (count != 0) { |
if ((s = args_get(args, 'p')) == NULL) { |
s = args_string(args, 0); |
if (count != 0) { |
if (args_has(args, 'F')) |
tmp = args_make_commands_get_command(cdata->state); |
cdata->template = format_single_from_target(item, s); |
xasprintf(&prompts, "(%s)", tmp); |
else |
free(tmp); |
cdata->template = xstrdup(s); |
} else { |
} else |
prompts = xstrdup(":"); |
cdata->template = xstrdup("%1"); |
space = 0; |
|
} |
if ((prompts = args_get(args, 'p')) != NULL) |
next_prompt = prompts; |
cdata->prompts = xstrdup(prompts); |
|
else if (count != 0) { |
|
n = strcspn(cdata->template, " ,"); |
|
xasprintf(&cdata->prompts, "(%.*s) ", (int)n, cdata->template); |
|
} else |
} else |
cdata->prompts = xstrdup(":"); |
next_prompt = prompts = xstrdup (s); |
|
if ((s = args_get(args, 'I')) != NULL) |
/* Get first prompt. */ |
next_input = inputs = xstrdup(s); |
cdata->next_prompt = cdata->prompts; |
|
comma = strsep(&cdata->next_prompt, ","); |
|
if (prompts == NULL) |
|
prompt = xstrdup(comma); |
|
else |
else |
xasprintf(&prompt, "%s ", comma); |
next_input = NULL; |
|
while ((prompt = strsep(&next_prompt, ",")) != NULL) { |
|
cdata->prompts = xreallocarray(cdata->prompts, cdata->count + 1, |
|
sizeof *cdata->prompts); |
|
if (!space) |
|
tmp = xstrdup(prompt); |
|
else |
|
xasprintf(&tmp, "%s ", prompt); |
|
cdata->prompts[cdata->count].prompt = tmp; |
|
|
/* Get initial prompt input. */ |
if (next_input != NULL) { |
if ((inputs = args_get(args, 'I')) != NULL) { |
input = strsep(&next_input, ","); |
cdata->inputs = xstrdup(inputs); |
if (input == NULL) |
cdata->next_input = cdata->inputs; |
input = ""; |
input = strsep(&cdata->next_input, ","); |
} else |
|
input = ""; |
|
cdata->prompts[cdata->count].input = xstrdup(input); |
|
|
|
cdata->count++; |
} |
} |
|
free(inputs); |
|
free(prompts); |
|
|
/* Get prompt type. */ |
|
if ((type = args_get(args, 'T')) != NULL) { |
if ((type = args_get(args, 'T')) != NULL) { |
cdata->prompt_type = status_prompt_type(type); |
cdata->prompt_type = status_prompt_type(type); |
if (cdata->prompt_type == PROMPT_TYPE_INVALID) { |
if (cdata->prompt_type == PROMPT_TYPE_INVALID) { |
|
|
cdata->flags |= PROMPT_INCREMENTAL; |
cdata->flags |= PROMPT_INCREMENTAL; |
else if (args_has(args, 'k')) |
else if (args_has(args, 'k')) |
cdata->flags |= PROMPT_KEY; |
cdata->flags |= PROMPT_KEY; |
status_prompt_set(tc, target, prompt, input, |
status_prompt_set(tc, target, cdata->prompts[0].prompt, |
cmd_command_prompt_callback, cmd_command_prompt_free, cdata, |
cdata->prompts[0].input, cmd_command_prompt_callback, |
cdata->flags, cdata->prompt_type); |
cmd_command_prompt_free, cdata, cdata->flags, cdata->prompt_type); |
free(prompt); |
|
|
|
if (!wait) |
if (!wait) |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
|
|
cmd_command_prompt_callback(struct client *c, void *data, const char *s, |
cmd_command_prompt_callback(struct client *c, void *data, const char *s, |
int done) |
int done) |
{ |
{ |
struct cmd_command_prompt_cdata *cdata = data; |
struct cmd_command_prompt_cdata *cdata = data; |
char *new_template, *prompt, *comma, *error; |
char *error; |
char *input = NULL; |
struct cmdq_item *item = cdata->item, *new_item; |
struct cmdq_item *item = cdata->item; |
struct cmd_list *cmdlist; |
enum cmd_parse_status status; |
struct cmd_command_prompt_prompt *prompt; |
|
|
if (s == NULL) |
if (s == NULL) |
goto out; |
goto out; |
if (done && (cdata->flags & PROMPT_INCREMENTAL)) |
|
goto out; |
|
|
|
new_template = cmd_template_replace(cdata->template, s, cdata->idx); |
|
if (done) { |
if (done) { |
free(cdata->template); |
if (cdata->flags & PROMPT_INCREMENTAL) |
cdata->template = new_template; |
goto out; |
} |
|
|
|
/* |
cmd_append_argv(&cdata->argc, &cdata->argv, s); |
* Check if there are more prompts; if so, get its respective input |
if (++cdata->current != cdata->count) { |
* and update the prompt data. |
prompt = &cdata->prompts[cdata->current]; |
*/ |
status_prompt_update(c, prompt->prompt, prompt->input); |
if (done && (comma = strsep(&cdata->next_prompt, ",")) != NULL) { |
return (1); |
xasprintf(&prompt, "%s ", comma); |
} |
input = strsep(&cdata->next_input, ","); |
|
status_prompt_update(c, prompt, input); |
|
|
|
free(prompt); |
|
cdata->idx++; |
|
return (1); |
|
} |
} |
|
|
if (item != NULL) { |
cmdlist = args_make_commands(cdata->state, cdata->argc, cdata->argv, |
status = cmd_parse_and_insert(new_template, &cdata->pi, item, |
&error); |
cmdq_get_state(item), &error); |
if (cmdlist == NULL) { |
} 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)); |
cmdq_append(c, cmdq_get_error(error)); |
free(error); |
free(error); |
|
} else if (item == NULL) { |
|
new_item = cmdq_get_command(cmdlist, NULL); |
|
cmdq_append(c, new_item); |
|
} else { |
|
new_item = cmdq_get_command(cmdlist, cmdq_get_state(item)); |
|
cmdq_insert_after(item, new_item); |
} |
} |
|
|
if (!done) |
|
free(new_template); |
|
if (c->prompt_inputcb != cmd_command_prompt_callback) |
if (c->prompt_inputcb != cmd_command_prompt_callback) |
return (1); |
return (1); |
|
|
|
|
cmd_command_prompt_free(void *data) |
cmd_command_prompt_free(void *data) |
{ |
{ |
struct cmd_command_prompt_cdata *cdata = data; |
struct cmd_command_prompt_cdata *cdata = data; |
|
u_int i; |
|
|
free(cdata->inputs); |
for (i = 0; i < cdata->count; i++) { |
|
free(cdata->prompts[i].prompt); |
|
free(cdata->prompts[i].input); |
|
} |
free(cdata->prompts); |
free(cdata->prompts); |
free(cdata->template); |
cmd_free_argv(cdata->argc, cdata->argv); |
|
args_make_commands_free(cdata->state); |
free(cdata); |
free(cdata); |
} |
} |