summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-21 16:31:11 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-21 16:31:11 +0000
commite70dd11ef41f69bd5e94f630194e6b3c4f3f2102 (patch)
tree52b2b8861caa9630a3dcd58e9f217a1b675515e7
parent6517f14165cdebf83a07ab9d4aeeb102b4e16e92 (diff)
downloadvim-git-8.2.4173.tar.gz
patch 8.2.4173: cannot use an import in 'foldexpr'v8.2.4173
Problem: Cannot use an import in 'foldexpr'. Solution: Set the script context to where 'foldexpr' was set. (closes #9584) Fix that the script context was not set for all buffers.
-rw-r--r--src/eval.c10
-rw-r--r--src/fold.c2
-rw-r--r--src/option.c6
-rw-r--r--src/proto/eval.pro4
-rw-r--r--src/structs.h5
-rw-r--r--src/testdir/test_vim9_import.vim39
-rw-r--r--src/version.c2
7 files changed, 59 insertions, 9 deletions
diff --git a/src/eval.c b/src/eval.c
index 9313c2720..ec34ef13e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -772,7 +772,7 @@ call_func_retlist(
return rettv.vval.v_list;
}
-#ifdef FEAT_FOLDING
+#if defined(FEAT_FOLDING) || defined(PROTO)
/*
* Evaluate "arg", which is 'foldexpr'.
* Note: caller must set "curwin" to match "arg".
@@ -780,14 +780,19 @@ call_func_retlist(
* give error messages.
*/
int
-eval_foldexpr(char_u *arg, int *cp)
+eval_foldexpr(win_T *wp, int *cp)
{
+ char_u *arg;
typval_T tv;
varnumber_T retval;
char_u *s;
+ sctx_T saved_sctx = current_sctx;
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
OPT_LOCAL);
+ arg = wp->w_p_fde;
+ current_sctx = wp->w_p_script_ctx[WV_FDE];
+
++emsg_off;
if (use_sandbox)
++sandbox;
@@ -818,6 +823,7 @@ eval_foldexpr(char_u *arg, int *cp)
--sandbox;
--textwinlock;
clear_evalarg(&EVALARG_EVALUATE, NULL);
+ current_sctx = saved_sctx;
return (int)retval;
}
diff --git a/src/fold.c b/src/fold.c
index f314d7a34..2a45d2108 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -3307,7 +3307,7 @@ foldlevelExpr(fline_T *flp)
// KeyTyped may be reset to 0 when calling a function which invokes
// do_cmdline(). To make 'foldopen' work correctly restore KeyTyped.
save_keytyped = KeyTyped;
- n = eval_foldexpr(flp->wp->w_p_fde, &c);
+ n = eval_foldexpr(flp->wp, &c);
KeyTyped = save_keytyped;
switch (c)
diff --git a/src/option.c b/src/option.c
index 2ec6ed552..4cc6142b6 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2604,7 +2604,13 @@ set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
if (indir & PV_BUF)
curbuf->b_p_script_ctx[indir & PV_MASK] = new_script_ctx;
else if (indir & PV_WIN)
+ {
curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx;
+ if (both)
+ // also setting the "all buffers" value
+ curwin->w_allbuf_opt.wo_script_ctx[indir & PV_MASK] =
+ new_script_ctx;
+ }
}
}
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index ac4a51cd9..b0e94a0d7 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -18,11 +18,9 @@ char_u *eval_to_string_safe(char_u *arg, int use_sandbox);
varnumber_T eval_to_number(char_u *expr);
typval_T *eval_expr(char_u *arg, exarg_T *eap);
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
-varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv);
-int call_func_noret(char_u *func, int argc, typval_T *argv);
void *call_func_retstr(char_u *func, int argc, typval_T *argv);
void *call_func_retlist(char_u *func, int argc, typval_T *argv);
-int eval_foldexpr(char_u *arg, int *cp);
+int eval_foldexpr(win_T *wp, int *cp);
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
void clear_lval(lval_T *lp);
void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int flags, char_u *op, int var_idx);
diff --git a/src/structs.h b/src/structs.h
index f73326883..e2f1de93a 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3695,6 +3695,8 @@ struct window_S
*/
winopt_T w_onebuf_opt;
winopt_T w_allbuf_opt;
+ // transform a pointer to a "onebuf" option into a "allbuf" option
+#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
// A few options have local flags for P_INSECURE.
#ifdef FEAT_STL_OPT
@@ -3718,9 +3720,6 @@ struct window_S
int w_briopt_list; // additional indent for lists
#endif
- // transform a pointer to a "onebuf" option into a "allbuf" option
-#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
-
long w_scbind_pos;
#ifdef FEAT_EVAL
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 6e61d0718..6ecea56a9 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -673,6 +673,45 @@ def Test_use_autoload_import_in_insert_completion()
&rtp = save_rtp
enddef
+def Test_use_autoload_import_in_fold_expression()
+ mkdir('Xdir/autoload', 'p')
+ var save_rtp = &rtp
+ exe 'set rtp^=' .. getcwd() .. '/Xdir'
+
+ var lines =<< trim END
+ vim9script
+ export def Expr(): string
+ return getline(v:lnum) =~ '^#' ? '>1' : '1'
+ enddef
+ g:fold_loaded = 'yes'
+ END
+ writefile(lines, 'Xdir/autoload/fold.vim')
+
+ lines =<< trim END
+ vim9script
+ import autoload 'fold.vim'
+ &foldexpr = 'fold.Expr()'
+ &foldmethod = 'expr'
+ &debug = 'throw'
+ END
+ new
+ setline(1, ['# one', 'text', '# two', 'text'])
+ g:fold_loaded = 'no'
+ CheckScriptSuccess(lines)
+ assert_equal('no', g:fold_loaded)
+ redraw
+ assert_equal('yes', g:fold_loaded)
+
+ # Check that script context of 'foldexpr' is copied to another buffer.
+ edit! otherfile
+ redraw
+
+ set foldexpr= foldmethod&
+ bwipe!
+ delete('Xdir', 'rf')
+ &rtp = save_rtp
+enddef
+
def Test_export_fails()
CheckScriptFailure(['export var some = 123'], 'E1042:')
CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
diff --git a/src/version.c b/src/version.c
index 45ae6d58f..a9a832378 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4173,
+/**/
4172,
/**/
4171,