diff options
| author | ZyX <kp-pav@yandex.ru> | 2017-04-01 23:57:34 +0300 | 
|---|---|---|
| committer | ZyX <kp-pav@yandex.ru> | 2017-05-10 15:52:48 +0300 | 
| commit | f4d5d5250a105b5593e3119f4ee37ea20272a34b (patch) | |
| tree | 307cdf0118e0463266dca1c6637a487a8589078a /src | |
| parent | d9023b84e63f51611cf55f72ca5e021d64ba7ce9 (diff) | |
| download | rneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.tar.gz rneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.tar.bz2 rneovim-f4d5d5250a105b5593e3119f4ee37ea20272a34b.zip | |
eval: Refactor get_user_input to support dictionary
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/eval.c | 160 | ||||
| -rw-r--r-- | src/nvim/eval/typval.c | 25 | 
2 files changed, 126 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;  } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 786b766689..e721ebe345 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1225,6 +1225,31 @@ const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,    return tv_get_string_buf(&di->di_tv, numbuf);  } +/// Get a string item from a dictionary +/// +/// @param[in]  d  Dictionary to get item from. +/// @param[in]  key  Dictionary key. +/// @param[in]  key_len  Key length. +/// @param[in]  numbuf  Numbuf for. +/// @param[in]  def  Default return when key does not exist. +/// +/// @return `def` when key does not exist, +///         NULL in case of type error, +///         string item value in case of success. +const char *tv_dict_get_string_buf_chk(const dict_T *const d, +                                       const char *const key, +                                       const ptrdiff_t key_len, +                                       char *const numbuf, +                                       const char *const def) +  FUNC_ATTR_WARN_UNUSED_RESULT +{ +  const dictitem_T *const di = tv_dict_find(d, key, key_len); +  if (di == NULL) { +    return def; +  } +  return tv_get_string_buf_chk(&di->di_tv, numbuf); +} +  /// Get a function from a dictionary  ///  /// @param[in]  d  Dictionary to get callback from. | 
