diff options
-rw-r--r-- | runtime/doc/diff.txt | 9 | ||||
-rw-r--r-- | runtime/doc/options.txt | 21 | ||||
-rw-r--r-- | src/nvim/eval.c | 46 | ||||
-rw-r--r-- | src/nvim/fold.c | 12 | ||||
-rw-r--r-- | src/nvim/indent.c | 3 | ||||
-rw-r--r-- | src/nvim/option.c | 12 | ||||
-rw-r--r-- | src/nvim/path.c | 5 | ||||
-rw-r--r-- | src/nvim/textformat.c | 4 |
8 files changed, 94 insertions, 18 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 |<SID>|, then it is replaced with the script ID (|local-function|). Example: > set diffexpr=s:MyDiffExpr() set diffexpr=<SID>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 |<SID>|, then it is replaced with the script ID (|local-function|). Example: > set patchexpr=s:MyPatchExpr() set patchexpr=<SID>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=<SID>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=<SID>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 |<SID>|, then it is replaced with the script ID (|local-function|). Example: > set indentexpr=s:MyIndentExpr() set indentexpr=<SID>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). diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8d38df8421..28ac1f3fbd 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; @@ -669,28 +677,46 @@ 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_free(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) { - 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) @@ -1059,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); @@ -1067,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) { @@ -1080,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; } 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; 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" 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) 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; } 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; } |