diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-08-03 07:42:52 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 23:42:52 +0000 |
commit | 383f6934720a203d093c762cbd5362092110f35f (patch) | |
tree | 00c2b4ff33f60e4b30247fb6fba197f9d5b9b3c3 /src/nvim/ex_getln.c | |
parent | e7f8349a2eec01dda531d93fecb8df920b042d9f (diff) | |
download | rneovim-383f6934720a203d093c762cbd5362092110f35f.tar.gz rneovim-383f6934720a203d093c762cbd5362092110f35f.tar.bz2 rneovim-383f6934720a203d093c762cbd5362092110f35f.zip |
refactor: move some functions out of eval.c (#29964)
- common_function() has always been in evalfunc.c in Vim
- return_register() has always been in evalfunc.c in Vim
- get_user_input() was moved to ex_getln.c in Vim 8.1.1957
- tv_get_lnum_buf() was moved to typval.c in Vim 8.2.0847
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r-- | src/nvim/ex_getln.c | 146 |
1 files changed, 138 insertions, 8 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index c8ca6f0e4e..8a34e03d91 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -267,6 +267,18 @@ static void init_incsearch_state(incsearch_state_T *s) save_viewstate(curwin, &s->old_viewstate); } +static void set_search_match(pos_T *t) +{ + // First move cursor to end of match, then to the start. This + // moves the whole match onto the screen when 'nowrap' is set. + t->lnum += search_match_lines; + t->col = search_match_endcol; + if (t->lnum > curbuf->b_ml.ml_line_count) { + t->lnum = curbuf->b_ml.ml_line_count; + coladvance(curwin, MAXCOL); + } +} + // Return true when 'incsearch' highlighting is to be done. // Sets search_first_line and search_last_line to the address range. static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s, @@ -4622,14 +4634,132 @@ char *script_get(exarg_T *const eap, size_t *const lenp) return (char *)ga.ga_data; } -static void set_search_match(pos_T *t) +/// This function is used by f_input() and f_inputdialog() functions. The third +/// argument to f_input() specifies the type of completion to use at the +/// prompt. The third argument to f_inputdialog() specifies the value to return +/// when the user cancels the prompt. +void get_user_input(const typval_T *const argvars, typval_T *const rettv, const bool inputdialog, + const bool secret) + FUNC_ATTR_NONNULL_ALL { - // First move cursor to end of match, then to the start. This - // moves the whole match onto the screen when 'nowrap' is set. - t->lnum += search_match_lines; - t->col = search_match_endcol; - if (t->lnum > curbuf->b_ml.ml_line_count) { - t->lnum = curbuf->b_ml.ml_line_count; - coladvance(curwin, MAXCOL); + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + const char *prompt; + const char *defstr = ""; + typval_T *cancelreturn = NULL; + typval_T cancelreturn_strarg2 = TV_INITIAL_VALUE; + const char *xp_name = NULL; + Callback input_callback = { .type = kCallbackNone }; + char prompt_buf[NUMBUFLEN]; + char defstr_buf[NUMBUFLEN]; + char cancelreturn_buf[NUMBUFLEN]; + char xp_name_buf[NUMBUFLEN]; + char def[1] = { 0 }; + if (argvars[0].v_type == VAR_DICT) { + if (argvars[1].v_type != VAR_UNKNOWN) { + emsg(_("E5050: {opts} must be the only argument")); + return; + } + 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; + } + dictitem_T *cancelreturn_di = tv_dict_find(dict, S_LEN("cancelreturn")); + if (cancelreturn_di != NULL) { + cancelreturn = &cancelreturn_di->di_tv; + } + 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; + } + if (!tv_dict_get_callback(dict, S_LEN("highlight"), &input_callback)) { + return; + } + } else { + prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf); + if (prompt == NULL) { + return; + } + if (argvars[1].v_type != VAR_UNKNOWN) { + defstr = tv_get_string_buf_chk(&argvars[1], defstr_buf); + if (defstr == NULL) { + return; + } + if (argvars[2].v_type != VAR_UNKNOWN) { + const char *const strarg2 = tv_get_string_buf_chk(&argvars[2], cancelreturn_buf); + if (strarg2 == NULL) { + return; + } + if (inputdialog) { + cancelreturn_strarg2.v_type = VAR_STRING; + cancelreturn_strarg2.vval.v_string = (char *)strarg2; + cancelreturn = &cancelreturn_strarg2; + } else { + xp_name = strarg2; + } + } + } + } + + 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 = 0; + if (parse_compl_arg(xp_name, xp_namelen, &xp_type, + &argt, &xp_arg) == FAIL) { + return; + } + } + + const bool cmd_silent_save = cmd_silent; + + 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, unlsess cmdline is externalized + const char *p = prompt; + if (!ui_has(kUICmdline)) { + const char *lastnl = strrchr(prompt, '\n'); + if (lastnl != NULL) { + p = lastnl + 1; + msg_start(); + msg_clr_eos(); + msg_puts_len(prompt, p - prompt, get_echo_attr()); + msg_didout = false; + msg_starthere(); + } } + cmdline_row = msg_row; + + stuffReadbuffSpec(defstr); + + const int save_ex_normal_busy = ex_normal_busy; + ex_normal_busy = 0; + rettv->vval.v_string = getcmdline_prompt(secret ? NUL : '@', p, get_echo_attr(), + xp_type, xp_arg, input_callback); + ex_normal_busy = save_ex_normal_busy; + callback_free(&input_callback); + + if (rettv->vval.v_string == NULL && cancelreturn != NULL) { + tv_copy(cancelreturn, rettv); + } + + 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; } |