# HG changeset patch # User Bram Moolenaar # Date 1567173604 -7200 # Node ID e4d3b6c466d49bc6b4145044894b5ab47156cdf2 # Parent 849f210a78a4cc8c5ff004ce85b2dc27c304c8fc patch 8.1.1943: more code can be moved to evalvars.c Commit: https://github.com/vim/vim/commit/8d71b54409ca6cf989dfb7d7fe265768fb7fe062 Author: Bram Moolenaar Date: Fri Aug 30 15:46:30 2019 +0200 patch 8.1.1943: more code can be moved to evalvars.c Problem: More code can be moved to evalvars.c. Solution: Move it, clean up comments. Also move some window related functions to window.c. (Yegappan Lakshmanan, closes #4874) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -6514,109 +6514,6 @@ ex_execute(exarg_T *eap) } /* - * Find window specified by "vp" in tabpage "tp". - */ - win_T * -find_win_by_nr( - typval_T *vp, - tabpage_T *tp) /* NULL for current tab page */ -{ - win_T *wp; - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr < 0) - return NULL; - if (nr == 0) - return curwin; - - FOR_ALL_WINDOWS_IN_TAB(tp, wp) - { - if (nr >= LOWEST_WIN_ID) - { - if (wp->w_id == nr) - return wp; - } - else if (--nr <= 0) - break; - } - if (nr >= LOWEST_WIN_ID) - { -#ifdef FEAT_TEXT_PROP - // check tab-local popup windows - for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; - // check global popup windows - for (wp = first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; -#endif - return NULL; - } - return wp; -} - -/* - * Find a window: When using a Window ID in any tab page, when using a number - * in the current tab page. - */ - win_T * -find_win_by_nr_or_id(typval_T *vp) -{ - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr >= LOWEST_WIN_ID) - return win_id2wp(tv_get_number(vp)); - return find_win_by_nr(vp, NULL); -} - -/* - * Find window specified by "wvp" in tabpage "tvp". - * Returns the tab page in 'ptp' - */ - win_T * -find_tabwin( - typval_T *wvp, // VAR_UNKNOWN for current window - typval_T *tvp, // VAR_UNKNOWN for current tab page - tabpage_T **ptp) -{ - win_T *wp = NULL; - tabpage_T *tp = NULL; - long n; - - if (wvp->v_type != VAR_UNKNOWN) - { - if (tvp->v_type != VAR_UNKNOWN) - { - n = (long)tv_get_number(tvp); - if (n >= 0) - tp = find_tabpage(n); - } - else - tp = curtab; - - if (tp != NULL) - { - wp = find_win_by_nr(wvp, tp); - if (wp == NULL && wvp->v_type == VAR_NUMBER - && wvp->vval.v_number != -1) - // A window with the specified number is not found - tp = NULL; - } - } - else - { - wp = curwin; - tp = curtab; - } - - if (ptp != NULL) - *ptp = tp; - - return wp; -} - -/* * Skip over the name of an option: "&option", "&g:option" or "&l:option". * "arg" points to the "&" or '+' when called, to "option" when returning. * Returns NULL when no option name found. Otherwise pointer to the char diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -21,7 +21,7 @@ #endif #ifdef MACOS_X -# include /* for time_t */ +# include // for time_t #endif static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); @@ -129,7 +129,6 @@ static void f_garbagecollect(typval_T *a static void f_get(typval_T *argvars, typval_T *rettv); static void f_getbufinfo(typval_T *argvars, typval_T *rettv); static void f_getbufline(typval_T *argvars, typval_T *rettv); -static void f_getbufvar(typval_T *argvars, typval_T *rettv); static void f_getchangelist(typval_T *argvars, typval_T *rettv); static void f_getchar(typval_T *argvars, typval_T *rettv); static void f_getcharmod(typval_T *argvars, typval_T *rettv); @@ -280,7 +279,6 @@ static void f_searchpos(typval_T *argvar static void f_server2client(typval_T *argvars, typval_T *rettv); static void f_serverlist(typval_T *argvars, typval_T *rettv); static void f_setbufline(typval_T *argvars, typval_T *rettv); -static void f_setbufvar(typval_T *argvars, typval_T *rettv); static void f_setcharsearch(typval_T *argvars, typval_T *rettv); static void f_setcmdpos(typval_T *argvars, typval_T *rettv); static void f_setenv(typval_T *argvars, typval_T *rettv); @@ -4394,73 +4392,6 @@ f_getbufline(typval_T *argvars, typval_T } /* - * "getbufvar()" function - */ - static void -f_getbufvar(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf; - buf_T *save_curbuf; - char_u *varname; - dictitem_T *v; - int done = FALSE; - - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - varname = tv_get_string_chk(&argvars[1]); - ++emsg_off; - buf = tv_get_buf(&argvars[0], FALSE); - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - - if (buf != NULL && varname != NULL) - { - /* set curbuf to be our buf, temporarily */ - save_curbuf = curbuf; - curbuf = buf; - - if (*varname == '&') - { - if (varname[1] == NUL) - { - /* get all buffer-local options in a dict */ - dict_T *opts = get_winbuf_options(TRUE); - - if (opts != NULL) - { - rettv_dict_set(rettv, opts); - done = TRUE; - } - } - else if (get_option_tv(&varname, rettv, TRUE) == OK) - /* buffer-local-option */ - done = TRUE; - } - else - { - /* Look up the variable. */ - /* Let getbufvar({nr}, "") return the "b:" dictionary. */ - v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, - 'b', varname, FALSE); - if (v != NULL) - { - copy_tv(&v->di_tv, rettv); - done = TRUE; - } - } - - /* restore previous notion of curbuf */ - curbuf = save_curbuf; - } - - if (!done && argvars[2].v_type != VAR_UNKNOWN) - /* use the default value */ - copy_tv(&argvars[2], rettv); - - --emsg_off; -} - -/* * "getchangelist()" function */ static void @@ -9749,63 +9680,6 @@ f_setbufline(typval_T *argvars, typval_T } } -/* - * "setbufvar()" function - */ - static void -f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) -{ - buf_T *buf; - char_u *varname, *bufvarname; - typval_T *varp; - char_u nbuf[NUMBUFLEN]; - - if (check_secure()) - return; - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - varname = tv_get_string_chk(&argvars[1]); - buf = tv_get_buf(&argvars[0], FALSE); - varp = &argvars[2]; - - if (buf != NULL && varname != NULL && varp != NULL) - { - if (*varname == '&') - { - long numval; - char_u *strval; - int error = FALSE; - aco_save_T aco; - - /* set curbuf to be our buf, temporarily */ - aucmd_prepbuf(&aco, buf); - - ++varname; - numval = (long)tv_get_number_chk(varp, &error); - strval = tv_get_string_buf_chk(varp, nbuf); - if (!error && strval != NULL) - set_option_value(varname, numval, strval, OPT_LOCAL); - - /* reset notion of buffer */ - aucmd_restbuf(&aco); - } - else - { - buf_T *save_curbuf = curbuf; - - bufvarname = alloc(STRLEN(varname) + 3); - if (bufvarname != NULL) - { - curbuf = buf; - STRCPY(bufvarname, "b:"); - STRCPY(bufvarname + 2, varname); - set_var(bufvarname, varp, TRUE); - vim_free(bufvarname); - curbuf = save_curbuf; - } - } - } -} - static void f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) { diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -46,10 +46,8 @@ static struct vimvar char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX } vimvars[VV_LEN] = { - /* - * The order here must match the VV_ defines in vim.h! - * Initializing a union does not work, leave tv.vval empty to get zero's. - */ + // The order here must match the VV_ defines in vim.h! + // Initializing a union does not work, leave tv.vval empty to get zero's. {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, {VV_NAME("count1", VAR_NUMBER), VV_RO}, {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, @@ -1592,7 +1590,7 @@ cat_prefix_varname(int prefix, char_u *n if (len > varnamebuflen) { vim_free(varnamebuf); - len += 10; /* some additional space */ + len += 10; // some additional space varnamebuf = alloc(len); if (varnamebuf == NULL) { @@ -1701,6 +1699,7 @@ set_vim_var_type(int idx, vartype_T type /* * Set number v: variable to "val". + * Note that this does not set the type, use set_vim_var_type() for that. */ void set_vim_var_nr(int idx, varnumber_T val) @@ -2078,7 +2077,7 @@ find_var(char_u *name, hashtab_T **htp, if (ret != NULL) return ret; - /* Search in parent scope for lambda */ + // Search in parent scope for lambda return find_var_in_scoped_ht(name, no_autoload || htp != NULL); } @@ -2222,9 +2221,9 @@ new_script_vars(scid_T id) if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) { - /* Re-allocating ga_data means that an ht_array pointing to - * ht_smallarray becomes invalid. We can recognize this: ht_mask is - * at its init value. Also reset "v_dict", it's always the same. */ + // Re-allocating ga_data means that an ht_array pointing to + // ht_smallarray becomes invalid. We can recognize this: ht_mask is + // at its init value. Also reset "v_dict", it's always the same. for (i = 1; i <= ga_scripts.ga_len; ++i) { ht = &SCRIPT_VARS(i); @@ -2269,8 +2268,8 @@ init_var_dict(dict_T *dict, dictitem_T * void unref_var_dict(dict_T *dict) { - /* Now the dict needs to be freed if no one else is using it, go back to - * normal reference counting. */ + // Now the dict needs to be freed if no one else is using it, go back to + // normal reference counting. dict->dv_refcount -= DO_NOT_FREE_CNT - 1; dict_unref(dict); } @@ -2817,7 +2816,7 @@ assert_error(garray_T *gap) struct vimvar *vp = &vimvars[VV_ERRORS]; if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) - /* Make sure v:errors is a list. */ + // Make sure v:errors is a list. set_vim_var_list(VV_ERRORS, list_alloc()); list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } @@ -2916,6 +2915,73 @@ f_getwinvar(typval_T *argvars, typval_T } /* + * "getbufvar()" function + */ + void +f_getbufvar(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf; + buf_T *save_curbuf; + char_u *varname; + dictitem_T *v; + int done = FALSE; + + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + varname = tv_get_string_chk(&argvars[1]); + ++emsg_off; + buf = tv_get_buf(&argvars[0], FALSE); + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (buf != NULL && varname != NULL) + { + // set curbuf to be our buf, temporarily + save_curbuf = curbuf; + curbuf = buf; + + if (*varname == '&') + { + if (varname[1] == NUL) + { + // get all buffer-local options in a dict + dict_T *opts = get_winbuf_options(TRUE); + + if (opts != NULL) + { + rettv_dict_set(rettv, opts); + done = TRUE; + } + } + else if (get_option_tv(&varname, rettv, TRUE) == OK) + // buffer-local-option + done = TRUE; + } + else + { + // Look up the variable. + // Let getbufvar({nr}, "") return the "b:" dictionary. + v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, + 'b', varname, FALSE); + if (v != NULL) + { + copy_tv(&v->di_tv, rettv); + done = TRUE; + } + } + + // restore previous notion of curbuf + curbuf = save_curbuf; + } + + if (!done && argvars[2].v_type != VAR_UNKNOWN) + // use the default value + copy_tv(&argvars[2], rettv); + + --emsg_off; +} + +/* * "settabvar()" function */ void @@ -2973,4 +3039,61 @@ f_setwinvar(typval_T *argvars, typval_T setwinvar(argvars, rettv, 0); } +/* + * "setbufvar()" function + */ + void +f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) +{ + buf_T *buf; + char_u *varname, *bufvarname; + typval_T *varp; + char_u nbuf[NUMBUFLEN]; + + if (check_secure()) + return; + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + varname = tv_get_string_chk(&argvars[1]); + buf = tv_get_buf(&argvars[0], FALSE); + varp = &argvars[2]; + + if (buf != NULL && varname != NULL && varp != NULL) + { + if (*varname == '&') + { + long numval; + char_u *strval; + int error = FALSE; + aco_save_T aco; + + // set curbuf to be our buf, temporarily + aucmd_prepbuf(&aco, buf); + + ++varname; + numval = (long)tv_get_number_chk(varp, &error); + strval = tv_get_string_buf_chk(varp, nbuf); + if (!error && strval != NULL) + set_option_value(varname, numval, strval, OPT_LOCAL); + + // reset notion of buffer + aucmd_restbuf(&aco); + } + else + { + buf_T *save_curbuf = curbuf; + + bufvarname = alloc(STRLEN(varname) + 3); + if (bufvarname != NULL) + { + curbuf = buf; + STRCPY(bufvarname, "b:"); + STRCPY(bufvarname + 2, varname); + set_var(bufvarname, varp, TRUE); + vim_free(bufvarname); + curbuf = save_curbuf; + } + } + } +} + #endif // FEAT_EVAL diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -80,9 +80,6 @@ void get_user_input(typval_T *argvars, t void ex_echo(exarg_T *eap); void ex_echohl(exarg_T *eap); void ex_execute(exarg_T *eap); -win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); -win_T *find_win_by_nr_or_id(typval_T *vp); -win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); char_u *find_option_end(char_u **arg, int *opt_flags); char_u *autoload_name(char_u *name); int script_autoload(char_u *name, int reload); diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -58,7 +58,9 @@ int var_exists(char_u *var); void f_gettabvar(typval_T *argvars, typval_T *rettv); void f_gettabwinvar(typval_T *argvars, typval_T *rettv); void f_getwinvar(typval_T *argvars, typval_T *rettv); +void f_getbufvar(typval_T *argvars, typval_T *rettv); void f_settabvar(typval_T *argvars, typval_T *rettv); void f_settabwinvar(typval_T *argvars, typval_T *rettv); void f_setwinvar(typval_T *argvars, typval_T *rettv); +void f_setbufvar(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/proto/window.pro b/src/proto/window.pro --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -89,5 +89,8 @@ win_T *win_id2wp(int id); win_T *win_id2wp_tp(int id, tabpage_T **tpp); int win_id2win(typval_T *argvars); void win_findbuf(typval_T *argvars, list_T *list); +win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); +win_T *find_win_by_nr_or_id(typval_T *vp); +win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); void get_framelayout(frame_T *fr, list_T *l, int outer); /* vim: set ft=c : */ diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1943, +/**/ 1942, /**/ 1941, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -6970,6 +6970,109 @@ win_findbuf(typval_T *argvars, list_T *l } /* + * Find window specified by "vp" in tabpage "tp". + */ + win_T * +find_win_by_nr( + typval_T *vp, + tabpage_T *tp) // NULL for current tab page +{ + win_T *wp; + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr < 0) + return NULL; + if (nr == 0) + return curwin; + + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + { + if (nr >= LOWEST_WIN_ID) + { + if (wp->w_id == nr) + return wp; + } + else if (--nr <= 0) + break; + } + if (nr >= LOWEST_WIN_ID) + { +#ifdef FEAT_TEXT_PROP + // check tab-local popup windows + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; + // check global popup windows + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; +#endif + return NULL; + } + return wp; +} + +/* + * Find a window: When using a Window ID in any tab page, when using a number + * in the current tab page. + */ + win_T * +find_win_by_nr_or_id(typval_T *vp) +{ + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr >= LOWEST_WIN_ID) + return win_id2wp(tv_get_number(vp)); + return find_win_by_nr(vp, NULL); +} + +/* + * Find window specified by "wvp" in tabpage "tvp". + * Returns the tab page in 'ptp' + */ + win_T * +find_tabwin( + typval_T *wvp, // VAR_UNKNOWN for current window + typval_T *tvp, // VAR_UNKNOWN for current tab page + tabpage_T **ptp) +{ + win_T *wp = NULL; + tabpage_T *tp = NULL; + long n; + + if (wvp->v_type != VAR_UNKNOWN) + { + if (tvp->v_type != VAR_UNKNOWN) + { + n = (long)tv_get_number(tvp); + if (n >= 0) + tp = find_tabpage(n); + } + else + tp = curtab; + + if (tp != NULL) + { + wp = find_win_by_nr(wvp, tp); + if (wp == NULL && wvp->v_type == VAR_NUMBER + && wvp->vval.v_number != -1) + // A window with the specified number is not found + tp = NULL; + } + } + else + { + wp = curwin; + tp = curtab; + } + + if (ptp != NULL) + *ptp = tp; + + return wp; +} + +/* * Get the layout of the given tab page for winlayout(). */ void