From d6e0f3dad2176b2619ea3ca2a8f622c00d4f78af Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:09:05 +0800 Subject: vim-patch:8.2.4179: 'foldtext' is evaluated in the current script context Problem: 'foldtext' is evaluated in the current script context. Solution: Use the script context where the option was set. https://github.com/vim/vim/commit/9530b580a7b71960dbbdb2b12a3aafeb540bd135 Script version is N/A. Co-authored-by: Bram Moolenaar --- src/nvim/fold.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/nvim/fold.c b/src/nvim/fold.c index a0869b54c9..2066da280a 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1742,16 +1742,19 @@ char *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo set_vim_var_string(VV_FOLDDASHES, dashes, -1); set_vim_var_nr(VV_FOLDLEVEL, (varnumber_T)level); - // skip evaluating foldtext on errors + // skip evaluating 'foldtext' on errors if (!got_fdt_error) { - win_T *save_curwin = curwin; + win_T *const save_curwin = curwin; + const sctx_T saved_sctx = current_sctx; + curwin = wp; curbuf = wp->w_buffer; + current_sctx = wp->w_p_script_ctx[WV_FDT].script_ctx; - emsg_silent++; // handle exceptions, but don't display errors + emsg_off++; // handle exceptions, but don't display errors text = eval_to_string_safe(wp->w_p_fdt, was_set_insecurely(wp, "foldtext", OPT_LOCAL)); - emsg_silent--; + emsg_off--; if (text == NULL || did_emsg) { got_fdt_error = true; @@ -1759,6 +1762,7 @@ char *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo curwin = save_curwin; curbuf = curwin->w_buffer; + current_sctx = saved_sctx; } last_lnum = lnum; last_wp = wp; -- cgit From 0c99ae7a88216f32ad188fc67ed00387c6ce2cae Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:14:01 +0800 Subject: vim-patch:8.2.4180: 'balloonexpr' is evaluated in the current script context Problem: 'balloonexpr' is evaluated in the current script context. Solution: Use the script context where the option was set. https://github.com/vim/vim/commit/5600a709f453045c80f92087acc0f855b4af377a Co-authored-by: Bram Moolenaar --- src/nvim/option.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/nvim/option.c b/src/nvim/option.c index 6d4e7de1a3..3b674ce726 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1913,6 +1913,18 @@ bool parse_winhl_opt(win_T *wp) return true; } +/// Get the script context of global option "name". +sctx_T *get_option_sctx(const char *const name) +{ + int idx = findoption(name); + + if (idx >= 0) { + return &options[idx].last_set.script_ctx; + } + siemsg("no such option: %s", name); + return NULL; +} + /// Set the script_ctx for an option, taking care of setting the buffer- or /// window-local value. void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) -- cgit From ba57566601725c5ac142a77b42d45d8d7f02a243 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:17:58 +0800 Subject: vim-patch:8.2.4181: Vim9: cannot use an import in 'diffexpr' Problem: Vim9: cannot use an import in 'diffexpr'. Solution: Set the script context when evaluating 'diffexpr'. Do not require 'diffexpr' to return a bool, it was ignored anyway. https://github.com/vim/vim/commit/7b29f6a3949743914f08410b6f6bd6237c2f2038 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8d38df8421..5eb7e2260f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -669,15 +669,24 @@ int eval_charconvert(const char *const enc_from, const char *const enc_to, void eval_diff(const char *const origfile, const char *const newfile, const char *const outfile) { - bool err = false; - + const sctx_T saved_sctx = current_sctx; set_vim_var_string(VV_FNAME_IN, origfile, -1); set_vim_var_string(VV_FNAME_NEW, newfile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - (void)eval_to_bool(p_dex, &err, NULL, false); + + sctx_T *ctx = get_option_sctx("diffexpr"); + if (ctx != NULL) { + current_sctx = *ctx; + } + + // errors are ignored + typval_T *tv = eval_expr(p_dex, NULL); + tv_clear(tv); + set_vim_var_string(VV_FNAME_IN, NULL, -1); set_vim_var_string(VV_FNAME_NEW, NULL, -1); set_vim_var_string(VV_FNAME_OUT, NULL, -1); + current_sctx = saved_sctx; } void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile) -- cgit From 9cf59acfaa2a050ce7fbc68d5435bf777618dedb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:21:03 +0800 Subject: vim-patch:8.2.4182: memory leak when evaluating 'diffexpr' Problem: Memory leak when evaluating 'diffexpr'. Solution: Use free_tv() instead of clear_tv(). https://github.com/vim/vim/commit/39b8944539a9cde553fe709e535fdfd37d0f9307 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5eb7e2260f..750d9df454 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -681,7 +681,7 @@ void eval_diff(const char *const origfile, const char *const newfile, const char // errors are ignored typval_T *tv = eval_expr(p_dex, NULL); - tv_clear(tv); + tv_free(tv); set_vim_var_string(VV_FNAME_IN, NULL, -1); set_vim_var_string(VV_FNAME_NEW, NULL, -1); -- cgit From 36f1e9824aaccfe7211388737aba1bdb0e37e0be Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:21:47 +0800 Subject: vim-patch:8.2.4183: cannot use an import in 'formatexpr' Problem: Cannot use an import in 'formatexpr'. Solution: Set the script context when evaluating 'formatexpr'. https://github.com/vim/vim/commit/3ba685eeefcfbbf895d70664357ef05f252d7b21 Co-authored-by: Bram Moolenaar --- src/nvim/textformat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index c406f0c302..dd13295c48 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -881,6 +881,7 @@ void op_formatexpr(oparg_T *oap) int fex_format(linenr_T lnum, long count, int c) { int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL); + const sctx_T save_sctx = current_sctx; // Set v:lnum to the first line number and v:count to the number of lines. // Set v:char to the character to be inserted (can be NUL). @@ -890,6 +891,8 @@ int fex_format(linenr_T lnum, long count, int c) // Make a copy, the option could be changed while calling it. char *fex = xstrdup(curbuf->b_p_fex); + current_sctx = curbuf->b_p_script_ctx[BV_FEX].script_ctx; + // Evaluate the function. if (use_sandbox) { sandbox++; @@ -901,6 +904,7 @@ int fex_format(linenr_T lnum, long count, int c) set_vim_var_string(VV_CHAR, NULL, -1); xfree(fex); + current_sctx = save_sctx; return r; } -- cgit From 96451e7f606947c33b11ca024fa76dedf47314b1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:22:54 +0800 Subject: vim-patch:8.2.4184: cannot use an import in 'includeexpr' Problem: Cannot use an import in 'includeexpr'. Solution: Set the script context when evaluating 'includeexpr' https://github.com/vim/vim/commit/47bcc5f4c83c158f43ac2ea7abfe99dbf5c2e098 Co-authored-by: Bram Moolenaar --- src/nvim/path.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvim/path.c b/src/nvim/path.c index 137a8da2bc..cf7cd98829 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1661,10 +1661,15 @@ void simplify_filename(char *filename) static char *eval_includeexpr(const char *const ptr, const size_t len) { + const sctx_T save_sctx = current_sctx; set_vim_var_string(VV_FNAME, ptr, (ptrdiff_t)len); + current_sctx = curbuf->b_p_script_ctx[BV_INEX].script_ctx; + char *res = eval_to_string_safe(curbuf->b_p_inex, was_set_insecurely(curwin, "includeexpr", OPT_LOCAL)); + set_vim_var_string(VV_FNAME, NULL, 0); + current_sctx = save_sctx; return res; } -- cgit From 5d3ad6fd9031040da856167d4672154149625e8f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:24:40 +0800 Subject: vim-patch:8.2.4185: cannot use an import in 'indentexpr' Problem: Cannot use an import in 'indentexpr'. Solution: Set the script context when evaluating 'indentexpr' https://github.com/vim/vim/commit/28e60cc088cadd25afb69ee636f0e2e34233ba4e Co-authored-by: Bram Moolenaar --- src/nvim/indent.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 8a65e88545..1d8bceae4e 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -1122,6 +1122,7 @@ int get_expr_indent(void) int save_set_curswant; int save_State; int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL); + const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed // * via :normal commands. @@ -1134,6 +1135,7 @@ int get_expr_indent(void) sandbox++; } textlock++; + current_sctx = curbuf->b_p_script_ctx[BV_INDE].script_ctx; // Need to make a copy, the 'indentexpr' option could be changed while // evaluating it. @@ -1145,6 +1147,7 @@ int get_expr_indent(void) sandbox--; } textlock--; + current_sctx = save_sctx; // Restore the cursor position so that 'indentexpr' doesn't need to. // Pretend to be in Insert mode, allow cursor past end of line for "o" -- cgit From cec42e07bc136f496135dfd8ed6e6c4d16a24e0d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:25:34 +0800 Subject: vim-patch:8.2.4186: cannot use an import in 'patchexpr' Problem: Cannot use an import in 'patchexpr'. Solution: Set the script context when evaluating 'patchexpr'. Do not require 'patchexpr' to return a bool, it was ignored anyway. https://github.com/vim/vim/commit/36c2add7f82bc5dbbfc45db31953ef9633c635b3 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 750d9df454..9a94d414f9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -691,15 +691,24 @@ void eval_diff(const char *const origfile, const char *const newfile, const char void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile) { - bool err = false; - + const sctx_T saved_sctx = current_sctx; set_vim_var_string(VV_FNAME_IN, origfile, -1); set_vim_var_string(VV_FNAME_DIFF, difffile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - (void)eval_to_bool(p_pex, &err, NULL, false); + + sctx_T *ctx = get_option_sctx("patchexpr"); + if (ctx != NULL) { + current_sctx = *ctx; + } + + // errors are ignored + typval_T *tv = eval_expr(p_pex, NULL); + tv_free(tv); + set_vim_var_string(VV_FNAME_IN, NULL, -1); set_vim_var_string(VV_FNAME_DIFF, NULL, -1); set_vim_var_string(VV_FNAME_OUT, NULL, -1); + current_sctx = saved_sctx; } void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip) -- cgit From f560c970591a2d8355768deb79a8bd41a56b43dc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:27:39 +0800 Subject: vim-patch:8.2.4193: cannot use an import in 'charconvert' Problem: Cannot use an import in 'charconvert'. Solution: Set the script context when evaluating 'charconvert'. Also expand script-local functions in 'charconvert'. https://github.com/vim/vim/commit/f4e88f2152c5975a6f4cfa7ccd745575fe4d1c78 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9a94d414f9..4096b5d0ee 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -647,19 +647,27 @@ void var_redir_stop(void) int eval_charconvert(const char *const enc_from, const char *const enc_to, const char *const fname_from, const char *const fname_to) { - bool err = false; + const sctx_T saved_sctx = current_sctx; set_vim_var_string(VV_CC_FROM, enc_from, -1); set_vim_var_string(VV_CC_TO, enc_to, -1); set_vim_var_string(VV_FNAME_IN, fname_from, -1); set_vim_var_string(VV_FNAME_OUT, fname_to, -1); + sctx_T *ctx = get_option_sctx("charconvert"); + if (ctx != NULL) { + current_sctx = *ctx; + } + + bool err = false; if (eval_to_bool(p_ccv, &err, NULL, false)) { err = true; } + set_vim_var_string(VV_CC_FROM, NULL, -1); set_vim_var_string(VV_CC_TO, NULL, -1); set_vim_var_string(VV_FNAME_IN, NULL, -1); set_vim_var_string(VV_FNAME_OUT, NULL, -1); + current_sctx = saved_sctx; if (err) { return FAIL; -- cgit From 481c6e6cac1d7219098408af5c396bada065be64 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:30:42 +0800 Subject: vim-patch:8.2.4197: cannot use an import in the "expr" part of 'spellsuggest' Problem: Cannot use an import in the "expr" part of 'spellsuggest'. Solution: Set the script context when evaluating "expr" of 'spellsuggest'. https://github.com/vim/vim/commit/2a7aa834583dea157eccf3e69827d2ff1d9fe9c7 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4096b5d0ee..28ac1f3fbd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1085,6 +1085,7 @@ list_T *eval_spell_expr(char *badword, char *expr) typval_T rettv; list_T *list = NULL; char *p = skipwhite(expr); + const sctx_T saved_sctx = current_sctx; // Set "v:val" to the bad word. prepare_vimvar(VV_VAL, &save_val); @@ -1093,6 +1094,10 @@ list_T *eval_spell_expr(char *badword, char *expr) if (p_verbose == 0) { emsg_off++; } + sctx_T *ctx = get_option_sctx("spellsuggest"); + if (ctx != NULL) { + current_sctx = *ctx; + } if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK) { if (rettv.v_type != VAR_LIST) { @@ -1106,6 +1111,7 @@ list_T *eval_spell_expr(char *badword, char *expr) emsg_off--; } restore_vimvar(VV_VAL, &save_val); + current_sctx = saved_sctx; return list; } -- cgit From 79a69337682ca0e3fc4d0bb9f70d851f8114bc9a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 15:32:49 +0800 Subject: vim-patch:partial:6f4754b9f725 Update runtime files https://github.com/vim/vim/commit/6f4754b9f7253d7e4ba527064a24aff1acdb1e8f Co-authored-by: Bram Moolenaar --- runtime/doc/diff.txt | 9 +++++++-- runtime/doc/options.txt | 21 ++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/runtime/doc/diff.txt b/runtime/doc/diff.txt index ead68c5f4f..2f174a404e 100644 --- a/runtime/doc/diff.txt +++ b/runtime/doc/diff.txt @@ -396,7 +396,9 @@ If the 'diffexpr' expression starts with s: or ||, then it is replaced with the script ID (|local-function|). Example: > set diffexpr=s:MyDiffExpr() set diffexpr=SomeDiffExpr() -< +Otherwise, the expression is evaluated in the context of the script where the +option was set, thus script-local items are available. + *E810* *E97* Vim will do a test if the diff output looks alright. If it doesn't, you will get an error message. Possible causes: @@ -452,5 +454,8 @@ If the 'patchexpr' expression starts with s: or ||, then it is replaced with the script ID (|local-function|). Example: > set patchexpr=s:MyPatchExpr() set patchexpr=SomePatchExpr() -< +Otherwise, the expression is evaluated in the context of the script where the +option was set, thus script-local items are available. + + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index dcaf37af20..7842394245 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2563,7 +2563,9 @@ A jump table for the options with a short description can be found at |Q_op|. 'foldexpr' 'fde' string (default: "0") local to window The expression used for when 'foldmethod' is "expr". It is evaluated - for each line to obtain its fold level. See |fold-expr|. + for each line to obtain its fold level. The context is set to the + script where 'foldexpr' was set, script-local items can be accessed. + See |fold-expr| for the usage. The expression will be evaluated in the |sandbox| if set from a modeline, see |sandbox-option|. @@ -2679,7 +2681,9 @@ A jump table for the options with a short description can be found at |Q_op|. 'foldtext' 'fdt' string (default: "foldtext()") local to window An expression which is used to specify the text displayed for a closed - fold. See |fold-foldtext|. + fold. The context is set to the script where 'foldexpr' was set, + script-local items can be accessed. See |fold-foldtext| for the + usage. The expression will be evaluated in the |sandbox| if set from a modeline, see |sandbox-option|. @@ -2720,7 +2724,9 @@ A jump table for the options with a short description can be found at |Q_op|. the script ID (|local-function|). Example: > set formatexpr=s:MyFormatExpr() set formatexpr=SomeFormatExpr() -< +< Otherwise, the expression is evaluated in the context of the script + where the option was set, thus script-local items are available. + The expression will be evaluated in the |sandbox| when set from a modeline, see |sandbox-option|. That stops the option from working, since changing the buffer text is not allowed. @@ -3334,7 +3340,9 @@ A jump table for the options with a short description can be found at |Q_op|. the script ID (|local-function|). Example: > setlocal includeexpr=s:MyIncludeExpr(v:fname) setlocal includeexpr=SomeIncludeExpr(v:fname) -< +< Otherwise, the expression is evaluated in the context of the script + where the option was set, thus script-local items are available. + The expression will be evaluated in the |sandbox| when set from a modeline, see |sandbox-option|. This option cannot be set in a modeline when 'modelineexpr' is off. @@ -3389,11 +3397,14 @@ A jump table for the options with a short description can be found at |Q_op|. The expression is evaluated with |v:lnum| set to the line number for which the indent is to be computed. The cursor is also in this line when the expression is evaluated (but it may be moved around). + If the expression starts with s: or ||, then it is replaced with the script ID (|local-function|). Example: > set indentexpr=s:MyIndentExpr() set indentexpr=SomeIndentExpr() -< +< Otherwise, the expression is evaluated in the context of the script + where the option was set, thus script-local items are available. + The expression must return the number of spaces worth of indent. It can return "-1" to keep the current indent (this means 'autoindent' is used for the indent). -- cgit