diff options
Diffstat (limited to 'src/nvim/eval/funcs.c')
| -rw-r--r-- | src/nvim/eval/funcs.c | 1042 |
1 files changed, 213 insertions, 829 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index f24285063e..3b9dc92137 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7,12 +7,14 @@ #include "nvim/api/private/converter.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" +#include "nvim/arglist.h" #include "nvim/ascii.h" #include "nvim/assert.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/cmdhist.h" #include "nvim/context.h" #include "nvim/cursor.h" #include "nvim/diff.h" @@ -27,10 +29,12 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/ex_docmd.h" +#include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/highlight_group.h" #include "nvim/if_cscope.h" @@ -45,6 +49,7 @@ #include "nvim/match.h" #include "nvim/math.h" #include "nvim/memline.h" +#include "nvim/menu.h" #include "nvim/mouse.h" #include "nvim/move.h" #include "nvim/msgpack_rpc/channel.h" @@ -52,18 +57,20 @@ #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/os/dl.h" -#include "nvim/os/input.h" #include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/plines.h" -#include "nvim/popupmnu.h" +#include "nvim/popupmenu.h" +#include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" +#include "nvim/runtime.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/sha256.h" #include "nvim/sign.h" #include "nvim/spell.h" +#include "nvim/spellsuggest.h" #include "nvim/state.h" #include "nvim/syntax.h" #include "nvim/tag.h" @@ -117,13 +124,12 @@ static va_list dummy_ap; char *get_function_name(expand_T *xp, int idx) { static int intidx = -1; - char_u *name; if (idx == 0) { intidx = -1; } if (intidx < 0) { - name = (char_u *)get_user_func_name(xp, idx); + char_u *name = (char_u *)get_user_func_name(xp, idx); if (name != NULL) { if (*name != NUL && *name != '<' && STRNCMP("g:", xp->xp_pattern, 2) == 0) { @@ -154,13 +160,12 @@ char *get_function_name(expand_T *xp, int idx) char *get_expr_name(expand_T *xp, int idx) { static int intidx = -1; - char_u *name; if (idx == 0) { intidx = -1; } if (intidx < 0) { - name = (char_u *)get_function_name(xp, idx); + char_u *name = (char_u *)get_function_name(xp, idx); if (name != NULL) { return (char *)name; } @@ -294,10 +299,9 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type == VAR_FLOAT) { float_op_wrapper(argvars, rettv, (FunPtr)&fabs); } else { - varnumber_T n; bool error = false; - n = tv_get_number_chk(&argvars[0], &error); + varnumber_T n = tv_get_number_chk(&argvars[0], &error); if (error) { rettv->vval.v_number = -1; } else if (n > 0) { @@ -371,77 +375,6 @@ static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - if (argvars[0].v_type == VAR_UNKNOWN) { - // use the current window - rettv->vval.v_number = ARGCOUNT; - } else if (argvars[0].v_type == VAR_NUMBER - && tv_get_number(&argvars[0]) == -1) { - // use the global argument list - rettv->vval.v_number = GARGCOUNT; - } else { - // use the argument list of the specified window - win_T *wp = find_win_by_nr_or_id(&argvars[0]); - if (wp != NULL) { - rettv->vval.v_number = WARGCOUNT(wp); - } else { - rettv->vval.v_number = -1; - } - } -} - -/// "argidx()" function -static void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = curwin->w_arg_idx; -} - -/// "arglistid" function -static void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = -1; - win_T *wp = find_tabwin(&argvars[0], &argvars[1]); - if (wp != NULL) { - rettv->vval.v_number = wp->w_alist->id; - } -} - -/// "argv(nr)" function -static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - aentry_T *arglist = NULL; - int argcount = -1; - - if (argvars[0].v_type != VAR_UNKNOWN) { - if (argvars[1].v_type == VAR_UNKNOWN) { - arglist = ARGLIST; - argcount = ARGCOUNT; - } else if (argvars[1].v_type == VAR_NUMBER - && tv_get_number(&argvars[1]) == -1) { - arglist = GARGLIST; - argcount = GARGCOUNT; - } else { - win_T *wp = find_win_by_nr_or_id(&argvars[1]); - if (wp != NULL) { - // Use the argument list of the specified window - arglist = WARGLIST(wp); - argcount = WARGCOUNT(wp); - } - } - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - int idx = (int)tv_get_number_chk(&argvars[0], NULL); - if (arglist != NULL && idx >= 0 && idx < argcount) { - rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx])); - } else if (idx == -1) { - get_arglist_as_rettv(arglist, argcount, rettv); - } - } else { - get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv); - } -} - /// "atan2()" function static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -479,8 +412,8 @@ static buf_T *find_buffer(typval_T *avar) } else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) { buf = buflist_findname_exp(avar->vval.v_string); if (buf == NULL) { - /* No full path name match, try a match with a URL or a "nofile" - * buffer, these don't use the full path. */ + // No full path name match, try a match with a URL or a "nofile" + // buffer, these don't use the full path. FOR_ALL_BUFFERS(bp) { if (bp->b_fname != NULL && (path_with_url(bp->b_fname) || bt_nofilename(bp)) @@ -632,17 +565,15 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Get buffer by number or pattern. buf_T *tv_get_buf(typval_T *tv, int curtab_only) { - char_u *name = (char_u *)tv->vval.v_string; - int save_magic; - char *save_cpo; - buf_T *buf; - if (tv->v_type == VAR_NUMBER) { return buflist_findnr((int)tv->vval.v_number); } if (tv->v_type != VAR_STRING) { return NULL; } + + char_u *name = (char_u *)tv->vval.v_string; + if (name == NULL || *name == NUL) { return curbuf; } @@ -651,13 +582,13 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only) } // Ignore 'magic' and 'cpoptions' here to make scripts portable - save_magic = p_magic; - p_magic = TRUE; - save_cpo = p_cpo; + int save_magic = p_magic; + p_magic = true; + char *save_cpo = p_cpo; p_cpo = ""; - buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name), - true, false, curtab_only)); + buf_T *buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name), + true, false, curtab_only)); p_magic = save_magic; p_cpo = save_cpo; @@ -686,10 +617,8 @@ buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL /// valid. buf_T *get_buf_arg(typval_T *arg) { - buf_T *buf; - emsg_off++; - buf = tv_get_buf(arg, false); + buf_T *buf = tv_get_buf(arg, false); emsg_off--; if (buf == NULL) { semsg(_("E158: Invalid buffer name: %s"), tv_get_string(arg)); @@ -735,13 +664,13 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp) /// "byteidx()" function static void f_byteidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - byteidx(argvars, rettv, FALSE); + byteidx(argvars, rettv, false); } /// "byteidxcomp()" function static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - byteidx(argvars, rettv, TRUE); + byteidx(argvars, rettv, true); } /// "call(func, arglist [, dict])" function @@ -758,7 +687,6 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool owned = false; char_u *func; partial_T *partial = NULL; - dict_T *selfdict = NULL; if (argvars[0].v_type == VAR_FUNC) { func = (char_u *)argvars[0].vval.v_string; } else if (argvars[0].v_type == VAR_PARTIAL) { @@ -776,6 +704,7 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; // type error or empty name } + dict_T *selfdict = NULL; if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -898,10 +827,9 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void get_col(typval_T *argvars, typval_T *rettv, bool charcol) { colnr_T col = 0; - pos_T *fp; int fnum = curbuf->b_fnum; - fp = var2fpos(&argvars[0], false, &fnum, charcol); + pos_T *fp = var2fpos(&argvars[0], false, &fnum, charcol); if (fp != NULL && fnum == curbuf->b_fnum) { if (fp->col == MAXCOL) { // '> can be MAXCOL, get the length of the line then @@ -984,9 +912,6 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "chdir(dir)" function static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *cwd; - CdScope scope = kCdScopeGlobal; - rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -997,7 +922,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Return the current directory - cwd = xmalloc(MAXPATHL); + char_u *cwd = xmalloc(MAXPATHL); if (os_dirname(cwd, MAXPATHL) != FAIL) { #ifdef BACKSLASH_IN_FILENAME slash_adjust(cwd); @@ -1006,6 +931,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } xfree(cwd); + CdScope scope = kCdScopeGlobal; if (curwin->w_localdir != NULL) { scope = kCdScopeWindow; } else if (curtab->tp_localdir != NULL) { @@ -1021,11 +947,8 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "cindent(lnum)" function static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - pos_T pos; - linenr_T lnum; - - pos = curwin->w_cursor; - lnum = tv_get_lnum(argvars); + pos_T pos = curwin->w_cursor; + linenr_T lnum = tv_get_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { curwin->w_cursor.lnum = lnum; rettv->vval.v_number = get_c_indent(); @@ -1060,14 +983,12 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char buf[NUMBUFLEN]; char buf2[NUMBUFLEN]; - const char *message; const char *buttons = NULL; int def = 1; int type = VIM_GENERIC; - const char *typestr; bool error = false; - message = tv_get_string_chk(&argvars[0]); + const char *message = tv_get_string_chk(&argvars[0]); if (message == NULL) { error = true; } @@ -1079,7 +1000,7 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[2].v_type != VAR_UNKNOWN) { def = (int)tv_get_number_chk(&argvars[2], &error); if (argvars[3].v_type != VAR_UNKNOWN) { - typestr = tv_get_string_buf_chk(&argvars[3], buf2); + const char *typestr = tv_get_string_buf_chk(&argvars[3], buf2); if (typestr == NULL) { error = true; } else { @@ -1152,15 +1073,13 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_LIST) { - listitem_T *li; - list_T *l; - long idx; + list_T *l = argvars[0].vval.v_list; - if ((l = argvars[0].vval.v_list) != NULL) { - li = tv_list_first(l); + if (l != NULL) { + listitem_T *li = tv_list_first(l); if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[3].v_type != VAR_UNKNOWN) { - idx = tv_get_number_chk(&argvars[3], &error); + long idx = tv_get_number_chk(&argvars[3], &error); if (!error) { li = tv_list_find(l, (int)idx); if (li == NULL) { @@ -1180,19 +1099,17 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_DICT) { - int todo; - dict_T *d; - hashitem_T *hi; + dict_T *d = argvars[0].vval.v_dict; - if ((d = argvars[0].vval.v_dict) != NULL) { + if (d != NULL) { if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[3].v_type != VAR_UNKNOWN) { emsg(_(e_invarg)); } } - todo = error ? 0 : (int)d->dv_hashtab.ht_used; - for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { + int todo = error ? 0 : (int)d->dv_hashtab.ht_used; + for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; if (tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &argvars[1], ic, false)) { @@ -1414,10 +1331,8 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "debugbreak()" function static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int pid; - rettv->vval.v_number = FAIL; - pid = (int)tv_get_number(&argvars[0]); + int pid = (int)tv_get_number(&argvars[0]); if (pid == 0) { emsg(_(e_invarg)); } else { @@ -1564,10 +1479,6 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "deletebufline()" function static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - linenr_T last; - buf_T *curbuf_save = NULL; - win_T *curwin_save = NULL; - buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { rettv->vval.v_number = 1; // FAIL @@ -1576,6 +1487,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) const bool is_curbuf = buf == curbuf; const bool save_VIsual_active = VIsual_active; + linenr_T last; const linenr_T first = tv_get_lnum_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { last = tv_get_lnum_buf(&argvars[2], buf); @@ -1589,6 +1501,8 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + buf_T *curbuf_save = NULL; + win_T *curwin_save = NULL; if (!is_curbuf) { VIsual_active = false; curbuf_save = curbuf; @@ -1660,8 +1574,6 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) static int change_start = 0; static int change_end = 0; static hlf_T hlID = (hlf_T)0; - int filler_lines; - int col; if (lnum < 0) { // ignore type error in {lnum} arg lnum = 0; @@ -1670,7 +1582,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) || changedtick != buf_get_changedtick(curbuf) || fnum != curbuf->b_fnum) { // New line, buffer, change: need to get the values. - filler_lines = diff_check(curwin, lnum); + int filler_lines = diff_check(curwin, lnum); if (filler_lines < 0) { if (filler_lines == -1) { change_start = MAXCOL; @@ -1692,7 +1604,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (hlID == HLF_CHD || hlID == HLF_TXD) { - col = (int)tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}. + int col = (int)tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}. if (col >= change_start && col <= change_end) { hlID = HLF_TXD; // Changed text. } else { @@ -2042,12 +1954,9 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "expand()" function static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - size_t len; char *errormsg; int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; - expand_T xpc; bool error = false; - char_u *result; #ifdef BACKSLASH_IN_FILENAME char_u *p_csl_save = p_csl; @@ -2066,7 +1975,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *s = tv_get_string(&argvars[0]); if (*s == '%' || *s == '#' || *s == '<') { emsg_off++; - result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL); + size_t len; + char_u *result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL); emsg_off--; if (rettv->v_type == VAR_LIST) { tv_list_alloc_ret(rettv, (result != NULL)); @@ -2085,6 +1995,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) options |= WILD_KEEP_ALL; } if (!error) { + expand_T xpc; ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; if (p_wic) { @@ -2151,8 +2062,6 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "flatten(list[, {maxdepth}])" function static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - list_T *list; - long maxdepth; bool error = false; if (argvars[0].v_type != VAR_LIST) { @@ -2160,6 +2069,7 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + long maxdepth; if (argvars[1].v_type == VAR_UNKNOWN) { maxdepth = 999999; } else { @@ -2173,7 +2083,7 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - list = argvars[0].vval.v_list; + list_T *list = argvars[0].vval.v_list; if (list != NULL && !var_check_lock(tv_list_locked(list), N_("flatten() argument"), @@ -2190,7 +2100,6 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const arg_errmsg = N_("extend() argument"); if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) { - long before; bool error = false; list_T *const l1 = argvars[0].vval.v_list; @@ -2198,7 +2107,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (!var_check_lock(tv_list_locked(l1), arg_errmsg, TV_TRANSLATE)) { listitem_T *item; if (argvars[2].v_type != VAR_UNKNOWN) { - before = (long)tv_get_number_chk(&argvars[2], &error); + long before = (long)tv_get_number_chk(&argvars[2], &error); if (error) { return; // Type error; errmsg already given. } @@ -2360,7 +2269,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) /// "filter()" function static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - filter_map(argvars, rettv, FALSE); + filter_map(argvars, rettv, false); } /// "finddir({fname}[, {path}[, {count}]])" function @@ -2440,130 +2349,6 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr) xfree(fbuf); } -/// "foldclosed()" function -static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end) -{ - const linenr_T lnum = tv_get_lnum(argvars); - if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { - linenr_T first; - linenr_T last; - if (hasFoldingWin(curwin, lnum, &first, &last, false, NULL)) { - if (end) { - rettv->vval.v_number = (varnumber_T)last; - } else { - rettv->vval.v_number = (varnumber_T)first; - } - return; - } - } - rettv->vval.v_number = -1; -} - -/// "foldclosed()" function -static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - foldclosed_both(argvars, rettv, FALSE); -} - -/// "foldclosedend()" function -static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - foldclosed_both(argvars, rettv, TRUE); -} - -/// "foldlevel()" function -static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - const linenr_T lnum = tv_get_lnum(argvars); - if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { - rettv->vval.v_number = foldLevel(lnum); - } -} - -/// "foldtext()" function -static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - linenr_T foldstart; - linenr_T foldend; - char_u *dashes; - linenr_T lnum; - char_u *s; - char_u *r; - int len; - char *txt; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - - foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART); - foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND); - dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES); - if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) { - // Find first non-empty line in the fold. - for (lnum = foldstart; lnum < foldend; lnum++) { - if (!linewhite(lnum)) { - break; - } - } - - // Find interesting text in this line. - s = (char_u *)skipwhite((char *)ml_get(lnum)); - // skip C comment-start - if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) { - s = (char_u *)skipwhite((char *)s + 2); - if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) { - s = (char_u *)skipwhite((char *)ml_get(lnum + 1)); - if (*s == '*') { - s = (char_u *)skipwhite((char *)s + 1); - } - } - } - unsigned long count = (unsigned long)foldend - (unsigned long)foldstart + 1; - txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count); - r = xmalloc(STRLEN(txt) - + STRLEN(dashes) // for %s - + 20 // for %3ld - + STRLEN(s)); // concatenated - sprintf((char *)r, txt, dashes, count); - len = (int)STRLEN(r); - STRCAT(r, s); - // remove 'foldmarker' and 'commentstring' - foldtext_cleanup(r + len); - rettv->vval.v_string = (char *)r; - } -} - -/// "foldtextresult(lnum)" function -static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - char_u *text; - char_u buf[FOLD_TEXT_LEN]; - static bool entered = false; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - if (entered) { - return; // reject recursive use - } - entered = true; - linenr_T lnum = tv_get_lnum(argvars); - // Treat illegal types and illegal string values for {lnum} the same. - if (lnum < 0) { - lnum = 0; - } - - foldinfo_T info = fold_info(curwin, lnum); - if (info.fi_lines > 0) { - text = get_foldtext(curwin, lnum, lnum + (linenr_T)info.fi_lines - 1, info, buf); - if (text == buf) { - text = vim_strsave(text); - } - rettv->vval.v_string = (char *)text; - } - - entered = false; -} - /// "foreground()" function static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr) {} @@ -2593,10 +2378,6 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "get()" function static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - listitem_T *li; - list_T *l; - dictitem_T *di; - dict_T *d; typval_T *tv = NULL; bool what_is_dict = false; @@ -2617,17 +2398,19 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_LIST) { - if ((l = argvars[0].vval.v_list) != NULL) { + list_T *l = argvars[0].vval.v_list; + if (l != NULL) { bool error = false; - li = tv_list_find(l, (int)tv_get_number_chk(&argvars[1], &error)); + listitem_T *li = tv_list_find(l, (int)tv_get_number_chk(&argvars[1], &error)); if (!error && li != NULL) { tv = TV_LIST_ITEM_TV(li); } } } else if (argvars[0].v_type == VAR_DICT) { - if ((d = argvars[0].vval.v_dict) != NULL) { - di = tv_dict_find(d, tv_get_string(&argvars[1]), -1); + dict_T *d = argvars[0].vval.v_dict; + if (d != NULL) { + dictitem_T *di = tv_dict_find(d, tv_get_string(&argvars[1]), -1); if (di != NULL) { tv = &di->di_tv; } @@ -2639,7 +2422,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type == VAR_PARTIAL) { pt = argvars[0].vval.v_partial; } else { - memset(&fref_pt, 0, sizeof(fref_pt)); + CLEAR_FIELD(fref_pt); fref_pt.pt_name = (char_u *)argvars[0].vval.v_string; pt = &fref_pt; } @@ -2851,147 +2634,6 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// "getchar()" and "getcharstr()" functions -static void getchar_common(typval_T *argvars, typval_T *rettv) - FUNC_ATTR_NONNULL_ALL -{ - varnumber_T n; - bool error = false; - - no_mapping++; - allow_keys++; - for (;;) { - // Position the cursor. Needed after a message that ends in a space, - // or if event processing caused a redraw. - ui_cursor_goto(msg_row, msg_col); - - if (argvars[0].v_type == VAR_UNKNOWN) { - // getchar(): blocking wait. - // TODO(bfredl): deduplicate shared logic with state_enter ? - if (!char_avail()) { - (void)os_inchar(NULL, 0, -1, 0, main_loop.events); - if (!multiqueue_empty(main_loop.events)) { - state_handle_k_event(); - continue; - } - } - n = safe_vgetc(); - } else if (tv_get_number_chk(&argvars[0], &error) == 1) { - // getchar(1): only check if char avail - n = vpeekc_any(); - } else if (error || vpeekc_any() == NUL) { - // illegal argument or getchar(0) and no char avail: return zero - n = 0; - } else { - // getchar(0) and char avail() != NUL: get a character. - // Note that vpeekc_any() returns K_SPECIAL for K_IGNORE. - n = safe_vgetc(); - } - - if (n == K_IGNORE - || n == K_MOUSEMOVE - || n == K_VER_SCROLLBAR - || n == K_HOR_SCROLLBAR) { - continue; - } - break; - } - no_mapping--; - allow_keys--; - - if (!ui_has_messages()) { - // redraw the screen after getchar() - update_screen(CLEAR); - } - - set_vim_var_nr(VV_MOUSE_WIN, 0); - set_vim_var_nr(VV_MOUSE_WINID, 0); - set_vim_var_nr(VV_MOUSE_LNUM, 0); - set_vim_var_nr(VV_MOUSE_COL, 0); - - rettv->vval.v_number = n; - if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) { - char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1 - int i = 0; - - // Turn a special key into three bytes, plus modifier. - if (mod_mask != 0) { - temp[i++] = K_SPECIAL; - temp[i++] = KS_MODIFIER; - temp[i++] = (char_u)mod_mask; - } - if (IS_SPECIAL(n)) { - temp[i++] = K_SPECIAL; - temp[i++] = (char_u)K_SECOND(n); - temp[i++] = K_THIRD(n); - } else { - i += utf_char2bytes((int)n, (char *)temp + i); - } - assert(i < 10); - temp[i++] = NUL; - rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)vim_strsave(temp); - - if (is_mouse_key((int)n)) { - int row = mouse_row; - int col = mouse_col; - int grid = mouse_grid; - linenr_T lnum; - win_T *wp; - int winnr = 1; - - if (row >= 0 && col >= 0) { - // Find the window at the mouse coordinates and compute the - // text position. - win_T *const win = mouse_find_win(&grid, &row, &col); - if (win == NULL) { - return; - } - (void)mouse_comp_pos(win, &row, &col, &lnum); - for (wp = firstwin; wp != win; wp = wp->w_next) { - ++winnr; - } - set_vim_var_nr(VV_MOUSE_WIN, winnr); - set_vim_var_nr(VV_MOUSE_WINID, wp->handle); - set_vim_var_nr(VV_MOUSE_LNUM, lnum); - set_vim_var_nr(VV_MOUSE_COL, col + 1); - } - } - } -} - -/// "getchar()" function -static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - getchar_common(argvars, rettv); -} - -/// "getcharstr()" function -static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - getchar_common(argvars, rettv); - - if (rettv->v_type == VAR_NUMBER) { - char temp[7]; // mbyte-char: 6, NUL: 1 - const varnumber_T n = rettv->vval.v_number; - int i = 0; - - if (n != 0) { - i += utf_char2bytes((int)n, (char *)temp); - } - assert(i < 7); - temp[i++] = NUL; - rettv->v_type = VAR_STRING; - rettv->vval.v_string = xstrdup(temp); - } -} - -/// "getcharmod()" function -static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = mod_mask; -} - static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool charcol) { pos_T *fp = NULL; @@ -3203,15 +2845,15 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Numbers of the scope objects (window, tab) we want the working directory // of. A `-1` means to skip this scope, a `0` means the current object. int scope_number[] = { - [kCdScopeWindow] = 0, // Number of window to look at. + [kCdScopeWindow] = 0, // Number of window to look at. [kCdScopeTabpage] = 0, // Number of tab to look at. }; char *cwd = NULL; // Current working directory to print char *from = NULL; // The original string to copy - tabpage_T *tp = curtab; // The tabpage to look at. - win_T *win = curwin; // The window to look at. + tabpage_T *tp = curtab; // The tabpage to look at. + win_T *win = curwin; // The window to look at. rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -3455,13 +3097,6 @@ static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_buffer_lines(curbuf, lnum, end, retlist, rettv); } -/// "getloclist()" function -static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - win_T *wp = find_win_by_nr_or_id(&argvars[0]); - get_qf_loc_list(false, wp, &argvars[1], rettv); -} - /// "getmarklist()" function static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -3483,8 +3118,6 @@ static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "getmousepos()" function static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *d; - win_T *wp; int row = mouse_row; int col = mouse_col; int grid = mouse_grid; @@ -3495,12 +3128,12 @@ static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) varnumber_T column = 0; tv_dict_alloc_ret(rettv); - d = rettv->vval.v_dict; + dict_T *d = rettv->vval.v_dict; tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1); tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1); - wp = mouse_find_win(&grid, &row, &col); + win_T *wp = mouse_find_win(&grid, &row, &col); if (wp != NULL) { int height = wp->w_height + wp->w_hsep_height + wp->w_status_height; // The height is adjusted by 1 when there is a bottom border. This is not @@ -3546,12 +3179,6 @@ static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) getpos_both(argvars, rettv, false, false); } -/// "getqflist()" functions -static void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - get_qf_loc_list(true, NULL, &argvars[0], rettv); -} - /// Common between getreg(), getreginfo() and getregtype(): get the register /// name from the first argument. /// Returns zero on error. @@ -3788,7 +3415,6 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Move the window wp into a new split of targetwin in a given direction static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags) { - int dir; int height = wp->w_height; win_T *oldwin = curwin; @@ -3802,6 +3428,7 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags } // Remove the old window and frame from the tree of frames + int dir; (void)winframe_remove(wp, &dir, NULL); win_remove(wp, NULL); last_status(false); // may need to remove last status line @@ -3826,12 +3453,8 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags /// "win_splitmove()" function static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - win_T *wp; - win_T *targetwin; - int flags = 0, size = 0; - - wp = find_win_by_nr_or_id(&argvars[0]); - targetwin = find_win_by_nr_or_id(&argvars[1]); + win_T *wp = find_win_by_nr_or_id(&argvars[0]); + win_T *targetwin = find_win_by_nr_or_id(&argvars[1]); if (wp == NULL || targetwin == NULL || wp == targetwin || !win_valid(wp) || !win_valid(targetwin) @@ -3841,6 +3464,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + int flags = 0, size = 0; + if (argvars[2].v_type != VAR_UNKNOWN) { dict_T *d; dictitem_T *di; @@ -3890,8 +3515,8 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) expand_T xpc; bool error = false; - /* When the optional second argument is non-zero, don't remove matches - * for 'wildignore' and don't put matches for 'suffixes' at the end. */ + // When the optional second argument is non-zero, don't remove matches + // for 'wildignore' and don't put matches for 'suffixes' at the end. rettv->v_type = VAR_STRING; if (argvars[1].v_type != VAR_UNKNOWN) { if (tv_get_number_chk(&argvars[1], &error)) { @@ -3964,7 +3589,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (file != NULL && !error) { garray_T ga; ga_init(&ga, (int)sizeof(char_u *), 10); - globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); + globpath((char *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); if (rettv->v_type == VAR_STRING) { rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n"); @@ -4306,87 +3931,6 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// "histadd()" function -static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - HistoryType histype; - - rettv->vval.v_number = false; - if (check_secure()) { - return; - } - const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error - histype = str != NULL ? get_histtype(str, strlen(str), false) : HIST_INVALID; - if (histype != HIST_INVALID) { - char buf[NUMBUFLEN]; - str = tv_get_string_buf(&argvars[1], buf); - if (*str != NUL) { - init_history(); - add_to_history(histype, (char_u *)str, false, NUL); - rettv->vval.v_number = true; - return; - } - } -} - -/// "histdel()" function -static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - int n; - const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error - if (str == NULL) { - n = 0; - } else if (argvars[1].v_type == VAR_UNKNOWN) { - // only one argument: clear entire history - n = clr_history(get_histtype(str, strlen(str), false)); - } else if (argvars[1].v_type == VAR_NUMBER) { - // index given: remove that entry - n = del_history_idx(get_histtype(str, strlen(str), false), - (int)tv_get_number(&argvars[1])); - } else { - // string given: remove all matching entries - char buf[NUMBUFLEN]; - n = del_history_entry(get_histtype(str, strlen(str), false), - (char_u *)tv_get_string_buf(&argvars[1], buf)); - } - rettv->vval.v_number = n; -} - -/// "histget()" function -static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - HistoryType type; - int idx; - - const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error - if (str == NULL) { - rettv->vval.v_string = NULL; - } else { - type = get_histtype(str, strlen(str), false); - if (argvars[1].v_type == VAR_UNKNOWN) { - idx = get_history_idx(type); - } else { - idx = (int)tv_get_ |