diff options
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8682139b32..faacf3c65a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -126,7 +126,7 @@ bool *eval_lavars_used = NULL; #define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars) #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) -static int echo_attr = 0; // attributes used for ":echo" +static int echo_hl_id = 0; // highlight id used for ":echo" /// Info used by a ":for" loop. typedef struct { @@ -460,6 +460,8 @@ void eval_init(void) set_vim_var_nr(VV_SEARCHFORWARD, 1); set_vim_var_nr(VV_HLSEARCH, 1); set_vim_var_nr(VV_COUNT1, 1); + set_vim_var_special(VV_EXITING, kSpecialVarNull); + set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER); set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING); set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC); @@ -475,7 +477,6 @@ void eval_init(void) set_vim_var_nr(VV_NUMBERMAX, VARNUMBER_MAX); set_vim_var_nr(VV_NUMBERMIN, VARNUMBER_MIN); set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8); - set_vim_var_special(VV_EXITING, kSpecialVarNull); set_vim_var_nr(VV_MAXCOL, MAXCOL); set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); @@ -921,13 +922,12 @@ int eval_expr_typval(const typval_T *expr, bool want_func, typval_T *argv, int a { if (expr->v_type == VAR_PARTIAL) { return eval_expr_partial(expr, argv, argc, rettv); - } else if (expr->v_type == VAR_FUNC || want_func) { + } + if (expr->v_type == VAR_FUNC || want_func) { return eval_expr_func(expr, argv, argc, rettv); - } else { - return eval_expr_string(expr, rettv); } - return OK; + return eval_expr_string(expr, rettv); } /// Like eval_to_bool() but using a typval_T instead of a string. @@ -1047,7 +1047,7 @@ char *eval_to_string_eap(char *arg, const bool join_list, exarg_T *eap, retval = typval2string(&tv, join_list); tv_clear(&tv); } - clear_evalarg(&EVALARG_EVALUATE, NULL); + clear_evalarg(&evalarg, NULL); return retval; } @@ -1367,7 +1367,7 @@ int eval_foldexpr(win_T *wp, int *cp) const bool use_sandbox = was_set_insecurely(wp, kOptFoldexpr, OPT_LOCAL); char *arg = skipwhite(wp->w_p_fde); - current_sctx = wp->w_p_script_ctx[WV_FDE].script_ctx; + current_sctx = wp->w_p_script_ctx[kWinOptFoldexpr].script_ctx; emsg_off++; if (use_sandbox) { @@ -1981,7 +1981,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, bool copy, const bool // handle +=, -=, *=, /=, %= and .= di = NULL; - if (eval_variable(lp->ll_name, (int)strlen(lp->ll_name), + if (eval_variable(lp->ll_name, (int)lp->ll_name_len, &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING) @@ -2631,7 +2631,7 @@ static int may_call_simple_func(const char *arg, typval_T *rettv) /// Handle zero level expression with optimization for a simple function call. /// Same arguments and return value as eval0(). -static int eval0_simple_funccal(char *arg, typval_T *rettv, exarg_T *eap, evalarg_T *const evalarg) +int eval0_simple_funccal(char *arg, typval_T *rettv, exarg_T *eap, evalarg_T *const evalarg) { int r = may_call_simple_func(arg, rettv); @@ -4788,6 +4788,7 @@ bool garbage_collect(bool testing) ABORTING(set_ref_in_callback)(&buf->b_ofu_cb, copyID, NULL, NULL); ABORTING(set_ref_in_callback)(&buf->b_tsrfu_cb, copyID, NULL, NULL); ABORTING(set_ref_in_callback)(&buf->b_tfu_cb, copyID, NULL, NULL); + ABORTING(set_ref_in_callback)(&buf->b_ffu_cb, copyID, NULL, NULL); } // 'completefunc', 'omnifunc' and 'thesaurusfunc' callbacks @@ -4799,6 +4800,9 @@ bool garbage_collect(bool testing) // 'tagfunc' callback ABORTING(set_ref_in_tagfunc)(copyID); + // 'findfunc' callback + ABORTING(set_ref_in_findfunc)(copyID); + FOR_ALL_TAB_WINDOWS(tp, wp) { // window-local variables ABORTING(set_ref_in_item)(&wp->w_winvar.di_tv, copyID, NULL, NULL); @@ -6850,11 +6854,11 @@ static char *make_expanded_name(const char *in_start, char *expr_start, char *ex char *temp_result = eval_to_string(expr_start + 1, false, false); if (temp_result != NULL) { - retval = xmalloc(strlen(temp_result) + (size_t)(expr_start - in_start) - + (size_t)(in_end - expr_end) + 1); - STRCPY(retval, in_start); - strcat(retval, temp_result); - strcat(retval, expr_end + 1); + size_t retvalsize = (size_t)(expr_start - in_start) + + strlen(temp_result) + + (size_t)(in_end - expr_end) + 1; + retval = xmalloc(retvalsize); + vim_snprintf(retval, retvalsize, "%s%s%s", in_start, temp_result, expr_end + 1); } xfree(temp_result); @@ -7869,12 +7873,12 @@ void ex_echo(exarg_T *eap) msg_start(); } } else if (eap->cmdidx == CMD_echo) { - msg_puts_attr(" ", echo_attr); + msg_puts_hl(" ", echo_hl_id, false); } char *tofree = encode_tv2echo(&rettv, NULL); if (*tofree != NUL) { msg_ext_set_kind("echo"); - msg_multiline(tofree, echo_attr, true, &need_clear); + msg_multiline(cstr_as_string(tofree), echo_hl_id, true, false, &need_clear); } xfree(tofree); } @@ -7900,13 +7904,13 @@ void ex_echo(exarg_T *eap) /// ":echohl {name}". void ex_echohl(exarg_T *eap) { - echo_attr = syn_name2attr(eap->arg); + echo_hl_id = syn_name2id(eap->arg); } -/// Returns the :echo attribute -int get_echo_attr(void) +/// Returns the :echo highlight id +int get_echo_hl_id(void) { - return echo_attr; + return echo_hl_id; } /// ":execute expr1 ..." execute the result of an expression. @@ -7957,7 +7961,7 @@ void ex_execute(exarg_T *eap) if (ret != FAIL && ga.ga_data != NULL) { if (eap->cmdidx == CMD_echomsg) { msg_ext_set_kind("echomsg"); - msg(ga.ga_data, echo_attr); + msg(ga.ga_data, echo_hl_id); } else if (eap->cmdidx == CMD_echoerr) { // We don't want to abort following commands, restore did_emsg. int save_did_emsg = did_emsg; @@ -8343,9 +8347,10 @@ repeat: char *const sub = xmemdupz(s, (size_t)(p - s)); char *const str = xmemdupz(*fnamep, *fnamelen); *usedlen = (size_t)(p + 1 - src); - s = do_string_sub(str, pat, sub, NULL, flags); + size_t slen; + s = do_string_sub(str, *fnamelen, pat, sub, NULL, flags, &slen); *fnamep = s; - *fnamelen = strlen(s); + *fnamelen = slen; xfree(*bufp); *bufp = s; didit = true; @@ -8384,12 +8389,14 @@ repeat: /// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL. /// "flags" can be "g" to do a global substitute. /// +/// @param ret_len length of returned buffer +/// /// @return an allocated string, NULL for error. -char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char *flags) +char *do_string_sub(char *str, size_t len, char *pat, char *sub, typval_T *expr, const char *flags, + size_t *ret_len) { regmatch_T regmatch; garray_T ga; - char *zero_width = NULL; // Make 'cpoptions' empty, so that the 'l' flag doesn't work here char *save_cpo = p_cpo; @@ -8397,14 +8404,15 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char ga_init(&ga, 1, 200); - int do_all = (flags[0] == 'g'); - regmatch.rm_ic = p_ic; regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); if (regmatch.regprog != NULL) { - int sublen; char *tail = str; - char *end = str + strlen(str); + char *end = str + len; + bool do_all = (flags[0] == 'g'); + int sublen; + char *zero_width = NULL; + while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { // Skip empty match except for first match. if (regmatch.startp[0] == regmatch.endp[0]) { @@ -8451,12 +8459,17 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char if (ga.ga_data != NULL) { STRCPY((char *)ga.ga_data + ga.ga_len, tail); + ga.ga_len += (int)(end - tail); } vim_regfree(regmatch.regprog); } - char *ret = xstrdup(ga.ga_data == NULL ? str : ga.ga_data); + if (ga.ga_data != NULL) { + str = ga.ga_data; + len = (size_t)ga.ga_len; + } + char *ret = xstrnsave(str, len); ga_clear(&ga); if (p_cpo == empty_string_option) { p_cpo = save_cpo; @@ -8470,6 +8483,10 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char free_string_option(save_cpo); } + if (ret_len != NULL) { + *ret_len = len; + } + return ret; } @@ -8609,7 +8626,7 @@ bool eval_has_provider(const char *feat, bool throw_if_fast) } if (throw_if_fast && !nlua_is_deferred_safe()) { - semsg(e_luv_api_disabled, "Vimscript function"); + semsg(e_fast_api_disabled, "Vimscript function"); return false; } |