Mercurial > vim
changeset 36380:adf986edc45d draft v9.1.0810
patch 9.1.0810: cannot easily adjust the |:find| command
Commit: https://github.com/vim/vim/commit/aeb1c97db5b9de4f4903e7f288f2aa5ad6c49440
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Tue Oct 22 23:42:20 2024 +0200
patch 9.1.0810: cannot easily adjust the |:find| command
Problem: cannot easily adjust the |:find| command
Solution: Add support for the 'findexpr' option (Yegappan Lakshmanan)
closes: #15901
closes: #15905
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 23 Oct 2024 00:00:03 +0200 |
parents | cbc679fe9443 |
children | 9edf351bc40e |
files | runtime/doc/eval.txt runtime/doc/options.txt runtime/doc/quickref.txt runtime/doc/tags runtime/doc/version9.txt src/buffer.c src/ex_docmd.c src/option.c src/option.h src/optiondefs.h src/optionstr.c src/proto/option.pro src/structs.h src/testdir/test_findfile.vim src/testdir/test_modeline.vim src/testdir/test_options.vim src/version.c |
diffstat | 17 files changed, 422 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 9.1. Last change: 2024 Jul 28 +*eval.txt* For Vim version 9.1. Last change: 2024 Oct 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2223,7 +2223,8 @@ v:fcs_choice What should happen after a *v:fname* *fname-variable* v:fname When evaluating 'includeexpr': the file name that was - detected. Empty otherwise. + detected. When evaluating 'findexpr': the argument passed to + the |:find| command. Empty otherwise. *v:fname_in* *fname_in-variable* v:fname_in The name of the input file. Valid while evaluating:
--- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3552,6 +3552,51 @@ A jump table for the options with a shor eob EndOfBuffer |hl-EndOfBuffer| lastline NonText |hl-NonText| + *'findexpr'* *'fexpr'* +'findexpr' 'fexpr' string (default "") + global or local to buffer |global-local| + {not available when compiled without the |+eval| + feature} + Expression that is evaluated to obtain the filename(s) for the |:find| + command. When this option is empty, the internal |file-searching| + mechanism is used. + + While evaluating the expression, the |v:fname| variable is set to the + argument of the |:find| command. + + The expression is evaluated only once per |:find| command invocation. + The expression can process all the directories specified in 'path'. + + If a match is found, the expression should return a |List| containing + one or more file names. If a match is not found, the expression + should return an empty List. + + If any errors are encountered during the expression evaluation, an + empty List is used as the return value. + + Using a function call without arguments is faster |expr-option-function| + + It is not allowed to change text or jump to another window while + evaluating 'findexpr' |textlock|. + + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + + Examples: +> + " Use glob() + func FindExprGlob() + return glob(v:fname, v:false, v:true) + endfunc + set findexpr=FindExprGlob() + + " Use the 'git ls-files' output + func FindGitFiles() + let fnames = systemlist('git ls-files') + return fnames->filter('v:val =~? v:fname') + endfunc + set findexpr=FindGitFiles() +< *'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'* 'fixendofline' 'fixeol' boolean (default on) local to buffer
--- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -1,4 +1,4 @@ -*quickref.txt* For Vim version 9.1. Last change: 2024 Mar 03 +*quickref.txt* For Vim version 9.1. Last change: 2024 Oct 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -707,6 +707,7 @@ Short explanation of each option: *opti 'fileignorecase' 'fic' ignore case when using file names 'filetype' 'ft' type of file, used for autocommands 'fillchars' 'fcs' characters to use for displaying special items +'findexpr' 'fexpr' expression to evaluate for |:find| 'fixendofline' 'fixeol' make sure last line in file has <EOL> 'fkmap' 'fk' obsolete option for Farsi 'foldclose' 'fcl' close a fold when the cursor leaves it
--- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -267,6 +267,7 @@ 'fenc' options.txt /*'fenc'* 'fencs' options.txt /*'fencs'* 'fex' options.txt /*'fex'* +'fexpr' options.txt /*'fexpr'* 'ff' options.txt /*'ff'* 'ffs' options.txt /*'ffs'* 'fic' options.txt /*'fic'* @@ -277,6 +278,7 @@ 'fileignorecase' options.txt /*'fileignorecase'* 'filetype' options.txt /*'filetype'* 'fillchars' options.txt /*'fillchars'* +'findexpr' options.txt /*'findexpr'* 'fixendofline' options.txt /*'fixendofline'* 'fixeol' options.txt /*'fixeol'* 'fk' options.txt /*'fk'*
--- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.1. Last change: 2024 Oct 14 +*version9.txt* For Vim version 9.1. Last change: 2024 Oct 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41649,6 +41649,8 @@ Options: ~ 'completeitemalign' Order of |complete-items| in Insert mode completion popup +'findexpr' Vim expression to obtain the results for a |:find| + command 'winfixbuf' Keep buffer focused in a window 'tabclose' Which tab page to focus after closing a tab page 't_xo' Terminal uses XON/XOFF handshaking (e.g. vt420)
--- a/src/buffer.c +++ b/src/buffer.c @@ -2412,6 +2412,7 @@ free_buf_options( clear_string_option(&buf->b_p_fp); #if defined(FEAT_EVAL) clear_string_option(&buf->b_p_fex); + clear_string_option(&buf->b_p_fexpr); #endif #ifdef FEAT_CRYPT # ifdef FEAT_SODIUM
--- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -6923,6 +6923,103 @@ ex_wrongmodifier(exarg_T *eap) eap->errmsg = ex_errmsg(e_invalid_command_str, eap->cmd); } +#ifdef FEAT_EVAL +/* + * Evaluate the 'findexpr' expression and return the result. When evaluating + * the expression, v:fname is set to the ":find" command argument. + */ + static list_T * +eval_findexpr(char_u *ptr, int len) +{ + sctx_T saved_sctx = current_sctx; + int use_sandbox = FALSE; + char_u *findexpr; + char_u *arg; + typval_T tv; + list_T *retlist = NULL; + + if (*curbuf->b_p_fexpr == NUL) + { + use_sandbox = was_set_insecurely((char_u *)"findexpr", OPT_GLOBAL); + findexpr = p_fexpr; + } + else + { + use_sandbox = was_set_insecurely((char_u *)"findexpr", OPT_LOCAL); + findexpr = curbuf->b_p_fexpr; + } + + set_vim_var_string(VV_FNAME, ptr, len); + current_sctx = curbuf->b_p_script_ctx[BV_FEXPR]; + + arg = skipwhite(findexpr); + + if (use_sandbox) + ++sandbox; + ++textlock; + + // Evaluate the expression. If the expression is "FuncName()" call the + // function directly. + if (eval0_simple_funccal(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL) + retlist = NULL; + else + { + if (tv.v_type == VAR_LIST) + retlist = list_copy(tv.vval.v_list, TRUE, TRUE, get_copyID()); + clear_tv(&tv); + } + if (use_sandbox) + --sandbox; + --textlock; + clear_evalarg(&EVALARG_EVALUATE, NULL); + + set_vim_var_string(VV_FNAME, NULL, 0); + current_sctx = saved_sctx; + + return retlist; +} + +/* + * Use 'findexpr' to find file 'findarg'. The 'count' argument is used to find + * the n'th matching file. + */ + static char_u * +findexpr_find_file(char_u *findarg, int findarg_len, int count) +{ + list_T *fname_list; + char_u *ret_fname = NULL; + char_u cc; + int fname_count; + + cc = findarg[findarg_len]; + findarg[findarg_len] = NUL; + + fname_list = eval_findexpr(findarg, findarg_len); + fname_count = list_len(fname_list); + + if (fname_count == 0) + semsg(_(e_cant_find_file_str_in_path), findarg); + else + { + if (count > fname_count) + semsg(_(e_no_more_file_str_found_in_path), findarg); + else + { + listitem_T *li = list_find(fname_list, count - 1); + if (li != NULL && li->li_tv.v_type == VAR_STRING) + ret_fname = vim_strsave(li->li_tv.vval.v_string); + } + } + + if (fname_list != NULL) + list_free(fname_list); + + findarg[findarg_len] = cc; + + return ret_fname; +} +#endif + /* * :sview [+command] file split window with new file, read-only * :split [[+command] file] split window with current or new file @@ -6972,11 +7069,22 @@ ex_splitview(exarg_T *eap) { char_u *file_to_find = NULL; char *search_ctx = NULL; - fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), - FNAME_MESS, TRUE, curbuf->b_ffname, - &file_to_find, &search_ctx); - vim_free(file_to_find); - vim_findfile_cleanup(search_ctx); + + if (*get_findexpr() != NUL) + { +#ifdef FEAT_EVAL + fname = findexpr_find_file(eap->arg, (int)STRLEN(eap->arg), + eap->addr_count > 0 ? eap->line2 : 1); +#endif + } + else + { + fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), + FNAME_MESS, TRUE, curbuf->b_ffname, + &file_to_find, &search_ctx); + vim_free(file_to_find); + vim_findfile_cleanup(search_ctx); + } if (fname == NULL) goto theend; eap->arg = fname; @@ -7241,27 +7349,37 @@ ex_find(exarg_T *eap) if (!check_can_set_curbuf_forceit(eap->forceit)) return; - char_u *fname; + char_u *fname = NULL; int count; char_u *file_to_find = NULL; char *search_ctx = NULL; - fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), FNAME_MESS, - TRUE, curbuf->b_ffname, &file_to_find, &search_ctx); - if (eap->addr_count > 0) - { - // Repeat finding the file "count" times. This matters when it appears - // several times in the path. - count = eap->line2; - while (fname != NULL && --count > 0) - { - vim_free(fname); - fname = find_file_in_path(NULL, 0, FNAME_MESS, - FALSE, curbuf->b_ffname, &file_to_find, &search_ctx); - } - } - VIM_CLEAR(file_to_find); - vim_findfile_cleanup(search_ctx); + if (*get_findexpr() != NUL) + { +#ifdef FEAT_EVAL + fname = findexpr_find_file(eap->arg, (int)STRLEN(eap->arg), + eap->addr_count > 0 ? eap->line2 : 1); +#endif + } + else + { + fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), FNAME_MESS, + TRUE, curbuf->b_ffname, &file_to_find, &search_ctx); + if (eap->addr_count > 0) + { + // Repeat finding the file "count" times. This matters when it appears + // several times in the path. + count = eap->line2; + while (fname != NULL && --count > 0) + { + vim_free(fname); + fname = find_file_in_path(NULL, 0, FNAME_MESS, + FALSE, curbuf->b_ffname, &file_to_find, &search_ctx); + } + } + VIM_CLEAR(file_to_find); + vim_findfile_cleanup(search_ctx); + } if (fname == NULL) return;
--- a/src/option.c +++ b/src/option.c @@ -6313,6 +6313,11 @@ unset_global_local_option(char_u *name, case PV_FP: clear_string_option(&buf->b_p_fp); break; +# ifdef FEAT_EVAL + case PV_FEXPR: + clear_string_option(&buf->b_p_fexpr); + break; +# endif # ifdef FEAT_QUICKFIX case PV_EFM: clear_string_option(&buf->b_p_efm); @@ -6391,6 +6396,9 @@ get_varp_scope(struct vimoption *p, int switch ((int)p->indir) { case PV_FP: return (char_u *)&(curbuf->b_p_fp); +#ifdef FEAT_EVAL + case PV_FEXPR: return (char_u *)&(curbuf->b_p_fexpr); +#endif #ifdef FEAT_QUICKFIX case PV_EFM: return (char_u *)&(curbuf->b_p_efm); case PV_GP: return (char_u *)&(curbuf->b_p_gp); @@ -6501,6 +6509,10 @@ get_varp(struct vimoption *p) #endif case PV_FP: return *curbuf->b_p_fp != NUL ? (char_u *)&(curbuf->b_p_fp) : p->var; +#ifdef FEAT_EVAL + case PV_FEXPR: return *curbuf->b_p_fexpr != NUL + ? (char_u *)&curbuf->b_p_fexpr : p->var; +#endif #ifdef FEAT_QUICKFIX case PV_EFM: return *curbuf->b_p_efm != NUL ? (char_u *)&(curbuf->b_p_efm) : p->var; @@ -6748,6 +6760,21 @@ get_equalprg(void) } /* + * Get the value of 'findexpr', either the buffer-local one or the global one. + */ + char_u * +get_findexpr(void) +{ +#ifdef FEAT_EVAL + if (*curbuf->b_p_fexpr == NUL) + return p_fexpr; + return curbuf->b_p_fexpr; +#else + return (char_u *)""; +#endif +} + +/* * Copy options from one window to another. * Used when splitting a window. */ @@ -7275,6 +7302,10 @@ buf_copy_options(buf_T *buf, int flags) buf->b_p_efm = empty_option; #endif buf->b_p_ep = empty_option; +#if defined(FEAT_EVAL) + buf->b_p_fexpr = vim_strsave(p_fexpr); + COPY_OPT_SCTX(buf, BV_FEXPR); +#endif buf->b_p_kp = empty_option; buf->b_p_path = empty_option; buf->b_p_tags = empty_option;
--- a/src/option.h +++ b/src/option.h @@ -596,6 +596,9 @@ EXTERN char_u *p_ffs; // 'fileformats' EXTERN int p_fic; // 'fileignorecase' EXTERN char_u *p_ft; // 'filetype' EXTERN char_u *p_fcs; // 'fillchar' +#ifdef FEAT_EVAL +EXTERN char_u *p_fexpr; // 'findexpr' +#endif EXTERN int p_fixeol; // 'fixendofline' #ifdef FEAT_FOLDING EXTERN char_u *p_fcl; // 'foldclose' @@ -1168,6 +1171,7 @@ enum , BV_EP , BV_ET , BV_FENC + , BV_FEXPR , BV_FP #ifdef FEAT_EVAL , BV_BEXPR
--- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -74,6 +74,7 @@ #define PV_FP OPT_BOTH(OPT_BUF(BV_FP)) #ifdef FEAT_EVAL # define PV_FEX OPT_BUF(BV_FEX) +# define PV_FEXPR OPT_BOTH(OPT_BUF(BV_FEXPR)) #endif #define PV_FF OPT_BUF(BV_FF) #define PV_FLP OPT_BUF(BV_FLP) @@ -958,6 +959,15 @@ static struct vimoption options[] = {(char_u *)"vert:|,fold:-,eob:~,lastline:@", (char_u *)0L} SCTX_INIT}, + {"findexpr", "fexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_SECURE, +#if defined(FEAT_EVAL) + (char_u *)&p_fexpr, PV_FEXPR, did_set_optexpr, NULL, + {(char_u *)"", (char_u *)0L} +#else + (char_u *)NULL, PV_NONE, NULL, NULL, + {(char_u *)0L, (char_u *)0L} +#endif + SCTX_INIT}, {"fixendofline", "fixeol", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)&p_fixeol, PV_FIXEOL, did_set_eof_eol_fixeol_bomb, NULL,
--- a/src/optionstr.c +++ b/src/optionstr.c @@ -324,6 +324,9 @@ check_buf_options(buf_T *buf) check_string_option(&buf->b_p_efm); #endif check_string_option(&buf->b_p_ep); +#ifdef FEAT_EVAL + check_string_option(&buf->b_p_fexpr); +#endif check_string_option(&buf->b_p_path); check_string_option(&buf->b_p_tags); check_string_option(&buf->b_p_tc); @@ -3132,8 +3135,8 @@ expand_set_nrformats(optexpand_T *args, #if defined(FEAT_EVAL) || defined(PROTO) /* * One of the '*expr' options is changed: 'balloonexpr', 'diffexpr', - * 'foldexpr', 'foldtext', 'formatexpr', 'includeexpr', 'indentexpr', - * 'patchexpr', 'printexpr' and 'charconvert'. + * 'findexpr', 'foldexpr', 'foldtext', 'formatexpr', 'includeexpr', + * 'indentexpr', 'patchexpr', 'printexpr' and 'charconvert'. * */ char *
--- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -120,6 +120,7 @@ char_u *get_option_var(int opt_idx); char_u *get_option_fullname(int opt_idx); opt_did_set_cb_T get_option_did_set_cb(int opt_idx); char_u *get_equalprg(void); +char_u *get_findexpr(void); void win_copy_options(win_T *wp_from, win_T *wp_to); void after_copy_winopt(win_T *wp); void copy_winopt(winopt_T *from, winopt_T *to);
--- a/src/structs.h +++ b/src/structs.h @@ -3327,6 +3327,9 @@ struct file_buffer char_u *b_p_efm; // 'errorformat' local value #endif char_u *b_p_ep; // 'equalprg' local value +#ifdef FEAT_EVAL + char_u *b_p_fexpr; // 'findexpr' local value +#endif char_u *b_p_path; // 'path' local value int b_p_ar; // 'autoread' local value char_u *b_p_tags; // 'tags' local value
--- a/src/testdir/test_findfile.vim +++ b/src/testdir/test_findfile.vim @@ -1,5 +1,7 @@ " Test findfile() and finddir() +source check.vim + let s:files = [ 'Xfinddir1/foo', \ 'Xfinddir1/bar', \ 'Xfinddir1/Xdir2/foo', @@ -281,4 +283,170 @@ func Test_find_non_existing_path() let &path = save_path endfunc +" Test for 'findexpr' +func Test_findexpr() + CheckUnix + call assert_equal('', &findexpr) + call writefile(['aFile'], 'Xfindexpr1.c', 'D') + call writefile(['bFile'], 'Xfindexpr2.c', 'D') + call writefile(['cFile'], 'Xfindexpr3.c', 'D') + + " basic tests + func FindExpr1() + let fnames = ['Xfindexpr1.c', 'Xfindexpr2.c', 'Xfindexpr3.c'] + "return fnames->copy()->filter('v:val =~? v:fname')->join("\n") + return fnames->copy()->filter('v:val =~? v:fname') + endfunc + + set findexpr=FindExpr1() + find Xfindexpr3 + call assert_match('Xfindexpr3.c', @%) + bw! + 2find Xfind + call assert_match('Xfindexpr2.c', @%) + bw! + call assert_fails('4find Xfind', 'E347: No more file "Xfind" found in path') + call assert_fails('find foobar', 'E345: Can''t find file "foobar" in path') + + sfind Xfindexpr2.c + call assert_match('Xfindexpr2.c', @%) + call assert_equal(2, winnr('$')) + %bw! + call assert_fails('sfind foobar', 'E345: Can''t find file "foobar" in path') + + tabfind Xfindexpr3.c + call assert_match('Xfindexpr3.c', @%) + call assert_equal(2, tabpagenr()) + %bw! + call assert_fails('tabfind foobar', 'E345: Can''t find file "foobar" in path') + + " Buffer-local option + set findexpr=['abc'] + new + setlocal findexpr=['def'] + find xxxx + call assert_equal('def', @%) + wincmd w + find xxxx + call assert_equal('abc', @%) + aboveleft new + call assert_equal("['abc']", &findexpr) + wincmd k + aboveleft new + call assert_equal("['abc']", &findexpr) + %bw! + + " Empty list + set findexpr=[] + call assert_fails('find xxxx', 'E345: Can''t find file "xxxx" in path') + + " Error cases + + " Syntax error in the expression + set findexpr=FindExpr1{} + call assert_fails('find Xfindexpr1.c', 'E15: Invalid expression') + + " Find expression throws an error + func FindExpr2() + throw 'find error' + endfunc + set findexpr=FindExpr2() + call assert_fails('find Xfindexpr1.c', 'find error') + + " Try using a null string as the expression + set findexpr=test_null_string() + call assert_fails('find Xfindexpr1.c', 'E345: Can''t find file "Xfindexpr1.c" in path') + + " Try to create a new window from the find expression + func FindExpr3() + new + return ["foo"] + endfunc + set findexpr=FindExpr3() + call assert_fails('find Xfindexpr1.c', 'E565: Not allowed to change text or change window') + + " Try to modify the current buffer from the find expression + func FindExpr4() + call setline(1, ['abc']) + return ["foo"] + endfunc + set findexpr=FindExpr4() + call assert_fails('find Xfindexpr1.c', 'E565: Not allowed to change text or change window') + + set findexpr& + delfunc! FindExpr1 + delfunc! FindExpr2 + delfunc! FindExpr3 + delfunc! FindExpr4 +endfunc + +" Test for using a script-local function for 'findexpr' +func Test_findexpr_scriptlocal_func() + func! s:FindExprScript() + let g:FindExprArg = v:fname + return ['xxx'] + endfunc + + set findexpr=s:FindExprScript() + call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr) + call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr) + new | only + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + set findexpr=<SID>FindExprScript() + call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr) + call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr) + new | only + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + let &findexpr = 's:FindExprScript()' + call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr) + new | only + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + let &findexpr = '<SID>FindExprScript()' + call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr) + new | only + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + set findexpr= + setglobal findexpr=s:FindExprScript() + setlocal findexpr= + call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr) + call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr) + call assert_equal('', &l:findexpr) + new | only + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + new | only + set findexpr= + setglobal findexpr= + setlocal findexpr=s:FindExprScript() + call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr) + call assert_equal(expand('<SID>') .. 'FindExprScript()', &l:findexpr) + call assert_equal('', &g:findexpr) + let g:FindExprArg = '' + find abc + call assert_equal('abc', g:FindExprArg) + bw! + + set findexpr= + delfunc s:FindExprScript +endfunc + " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_modeline.vim +++ b/src/testdir/test_modeline.vim @@ -208,6 +208,7 @@ func Test_modeline_fails_always() call s:modeline_fails('equalprg', 'equalprg=Something()', 'E520:') call s:modeline_fails('errorfile', 'errorfile=Something()', 'E520:') call s:modeline_fails('exrc', 'exrc=Something()', 'E520:') + call s:modeline_fails('findexpr', 'findexpr=Something()', 'E520:') call s:modeline_fails('formatprg', 'formatprg=Something()', 'E520:') call s:modeline_fails('fsync', 'fsync=Something()', 'E520:') call s:modeline_fails('grepprg', 'grepprg=Something()', 'E520:')
--- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -1570,7 +1570,7 @@ endfunc " Test for changing options in a sandbox func Test_opt_sandbox() - for opt in ['backupdir', 'cdpath', 'exrc'] + for opt in ['backupdir', 'cdpath', 'exrc', 'findexpr'] call assert_fails('sandbox set ' .. opt .. '?', 'E48:') call assert_fails('sandbox let &' .. opt .. ' = 1', 'E48:') endfor