aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-04-01 23:57:34 +0300
committerZyX <kp-pav@yandex.ru>2017-05-10 15:52:48 +0300
commitf4d5d5250a105b5593e3119f4ee37ea20272a34b (patch)
tree307cdf0118e0463266dca1c6637a487a8589078a /src/nvim/eval.c
parentd9023b84e63f51611cf55f72ca5e021d64ba7ce9 (diff)
downloadrneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.tar.gz
rneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.tar.bz2
rneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.zip
eval: Refactor get_user_input to support dictionary
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c160
1 files changed, 101 insertions, 59 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 56a6632fad..780a33eced 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -10978,81 +10978,123 @@ void get_user_input(const typval_T *const argvars,
typval_T *const rettv, const bool inputdialog)
FUNC_ATTR_NONNULL_ALL
{
- const char *prompt = tv_get_string_chk(&argvars[0]);
- int cmd_silent_save = cmd_silent;
- int xp_type = EXPAND_NOTHING;
- char_u *xp_arg = NULL;
-
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- cmd_silent = FALSE; /* Want to see the prompt. */
- if (prompt != NULL) {
- // Only the part of the message after the last NL is considered as
- // prompt for the command line.
- const char *p = strrchr(prompt, '\n');
- if (p == NULL) {
- p = prompt;
- } else {
- p++;
- msg_start();
- msg_clr_eos();
- msg_puts_attr_len(prompt, p - prompt, echo_attr);
- msg_didout = false;
- msg_starthere();
+ const char *prompt = "";
+ const char *defstr = "";
+ const char *cancelreturn = NULL;
+ const char *xp_name = NULL;
+ char prompt_buf[NUMBUFLEN];
+ char defstr_buf[NUMBUFLEN];
+ char cancelreturn_buf[NUMBUFLEN];
+ char xp_name_buf[NUMBUFLEN];
+ if (argvars[0].v_type == VAR_DICT) {
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ emsgf(
+ _("E5050: When providing {opts} argument no more arguments follow"));
+ return;
+ }
+ const dict_T *const dict = argvars[0].vval.v_dict;
+ prompt = tv_dict_get_string_buf_chk(dict, S_LEN("prompt"), prompt_buf, "");
+ if (prompt == NULL) {
+ return;
+ }
+ defstr = tv_dict_get_string_buf_chk(dict, S_LEN("default"), defstr_buf, "");
+ if (defstr == NULL) {
+ return;
+ }
+ char def[1] = { 0 };
+ cancelreturn = tv_dict_get_string_buf_chk(dict, S_LEN("cancelreturn"),
+ cancelreturn_buf, def);
+ if (cancelreturn == NULL) { // error
+ return;
+ }
+ if (*cancelreturn == NUL) {
+ cancelreturn = NULL;
+ }
+ xp_name = tv_dict_get_string_buf_chk(dict, S_LEN("completion"),
+ xp_name_buf, def);
+ if (xp_name == NULL) { // error
+ return;
+ }
+ if (xp_name == def) { // default to NULL
+ xp_name = NULL;
+ }
+ } else {
+ prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf);
+ if (prompt == NULL) {
+ return;
}
- cmdline_row = msg_row;
-
- const char *defstr = "";
- char buf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN) {
- defstr = tv_get_string_buf_chk(&argvars[1], buf);
- if (defstr != NULL) {
- stuffReadbuffSpec(defstr);
+ defstr = tv_get_string_buf_chk(&argvars[1], defstr_buf);
+ if (defstr == NULL) {
+ return;
}
-
- if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) {
- char buf2[NUMBUFLEN];
- // input() with a third argument: completion
- rettv->vval.v_string = NULL;
-
- const char *const xp_name = tv_get_string_buf_chk(&argvars[2], buf2);
- if (xp_name == NULL) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ const char *const arg2 = tv_get_string_buf_chk(&argvars[2],
+ cancelreturn_buf);
+ if (arg2 == NULL) {
return;
}
-
- const int xp_namelen = (int)strlen(xp_name);
-
- uint32_t argt;
- if (parse_compl_arg((char_u *)xp_name, xp_namelen, &xp_type, &argt,
- &xp_arg) == FAIL) {
- return;
+ if (inputdialog) {
+ cancelreturn = arg2;
+ } else {
+ xp_name = arg2;
}
}
}
+ }
- if (defstr != NULL) {
- int save_ex_normal_busy = ex_normal_busy;
- ex_normal_busy = 0;
- rettv->vval.v_string =
- getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, echo_attr,
- xp_type, xp_arg);
- ex_normal_busy = save_ex_normal_busy;
- }
- if (inputdialog && rettv->vval.v_string == NULL
- && argvars[1].v_type != VAR_UNKNOWN
- && argvars[2].v_type != VAR_UNKNOWN) {
- char buf[NUMBUFLEN];
- rettv->vval.v_string = (char_u *)xstrdup(tv_get_string_buf(
- &argvars[2], buf));
+ int xp_type = EXPAND_NOTHING;
+ char *xp_arg = NULL;
+ if (xp_name != NULL) {
+ // input() with a third argument: completion
+ const int xp_namelen = (int)strlen(xp_name);
+
+ uint32_t argt;
+ if (parse_compl_arg((char_u *)xp_name, xp_namelen, &xp_type,
+ &argt, (char_u **)&xp_arg) == FAIL) {
+ return;
}
+ }
- xfree(xp_arg);
+ int cmd_silent_save = cmd_silent;
- /* since the user typed this, no need to wait for return */
- need_wait_return = FALSE;
- msg_didout = FALSE;
+ cmd_silent = false; // Want to see the prompt.
+ // Only the part of the message after the last NL is considered as
+ // prompt for the command line.
+ const char *p = strrchr(prompt, '\n');
+ if (p == NULL) {
+ p = prompt;
+ } else {
+ p++;
+ msg_start();
+ msg_clr_eos();
+ msg_puts_attr_len(prompt, p - prompt, echo_attr);
+ msg_didout = false;
+ msg_starthere();
}
+ cmdline_row = msg_row;
+
+ stuffReadbuffSpec(defstr);
+
+ int save_ex_normal_busy = ex_normal_busy;
+ ex_normal_busy = 0;
+ rettv->vval.v_string =
+ getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, echo_attr,
+ xp_type, (char_u *)xp_arg);
+ ex_normal_busy = save_ex_normal_busy;
+
+ if (rettv->vval.v_string == NULL && cancelreturn != NULL) {
+ rettv->vval.v_string = (char_u *)xstrdup(cancelreturn);
+ }
+
+ xfree(xp_arg);
+
+ // Since the user typed this, no need to wait for return.
+ need_wait_return = false;
+ msg_didout = false;
cmd_silent = cmd_silent_save;
}