summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2021-12-26 10:51:39 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-26 10:51:39 +0000
commit8bb65f230d3025037f34021a72616038da0601ee (patch)
tree1edaf57b7fbe5e3c30a174026f5389f8b98b7376 /src
parentec86520f946a40d5c4a92d6a11d6928faa13abd4 (diff)
patch 8.2.3900: it is not easy to use a script-local function for an optionv8.2.3900
Problem: It is not easy to use a script-local function for an option. Solution: recognize s: and <SID> at the start of the expression. (Yegappan Lakshmanan, closes #9401)
Diffstat (limited to 'src')
-rw-r--r--src/optionstr.c91
-rw-r--r--src/testdir/test_diffmode.vim20
-rw-r--r--src/testdir/test_edit.vim10
-rw-r--r--src/testdir/test_fold.vim26
-rw-r--r--src/testdir/test_gf.vim26
-rw-r--r--src/testdir/test_gui.vim9
-rw-r--r--src/testdir/test_hardcopy.vim8
-rw-r--r--src/testdir/test_normal.vim39
-rw-r--r--src/version.c2
9 files changed, 223 insertions, 8 deletions
diff --git a/src/optionstr.c b/src/optionstr.c
index dbb93cdc97..c69354eced 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -2026,14 +2026,6 @@ ambw_end:
newFoldLevel();
}
}
-# ifdef FEAT_EVAL
- // 'foldexpr'
- else if (varp == &curwin->w_p_fde)
- {
- if (foldmethodIsExpr(curwin))
- foldUpdateAll(curwin);
- }
-# endif
// 'foldmarker'
else if (gvarp == &curwin->w_allbuf_opt.wo_fmr)
{
@@ -2307,6 +2299,89 @@ ambw_end:
# endif
#endif
+#ifdef FEAT_EVAL
+ // '*expr' options
+ else if (
+# ifdef FEAT_BEVAL
+ varp == &p_bexpr ||
+# endif
+# ifdef FEAT_DIFF
+ varp == &p_dex ||
+# endif
+# ifdef FEAT_FOLDING
+ varp == &curwin->w_p_fde ||
+# endif
+ gvarp == &p_fex ||
+# ifdef FEAT_FIND_ID
+ gvarp == &p_inex ||
+# endif
+# ifdef FEAT_CINDENT
+ gvarp == &p_inde ||
+# endif
+# ifdef FEAT_DIFF
+ varp == &p_pex ||
+# endif
+# ifdef FEAT_POSTSCRIPT
+ varp == &p_pexpr ||
+# endif
+ FALSE
+ )
+ {
+ char_u **p_opt = NULL;
+ char_u *name;
+
+ // If the option value starts with <SID> or s:, then replace that with
+ // the script identifier.
+# ifdef FEAT_BEVAL
+ if (varp == &p_bexpr) // 'balloonexpr'
+ p_opt = (opt_flags & OPT_LOCAL) ? &curbuf->b_p_bexpr : &p_bexpr;
+# endif
+# ifdef FEAT_DIFF
+ if (varp == &p_dex) // 'diffexpr'
+ p_opt = &p_dex;
+# endif
+# ifdef FEAT_FOLDING
+ if(varp == &curwin->w_p_fde) // 'foldexpr'
+ p_opt = &curwin->w_p_fde;
+# endif
+ if (gvarp == &p_fex) // 'formatexpr'
+ p_opt = &curbuf->b_p_fex;
+# ifdef FEAT_FIND_ID
+ if (gvarp == &p_inex) // 'includeexpr'
+ p_opt = &curbuf->b_p_inex;
+# endif
+# ifdef FEAT_CINDENT
+ if (gvarp == &p_inde) // 'indentexpr'
+ p_opt = &curbuf->b_p_inde;
+# endif
+# ifdef FEAT_DIFF
+ if (varp == &p_pex) // 'patchexpr'
+ p_opt = &p_pex;
+# endif
+# ifdef FEAT_POSTSCRIPT
+ if (varp == &p_pexpr) // 'printexpr'
+ p_opt = &p_pexpr;
+# endif
+
+ if (p_opt != NULL)
+ {
+ name = get_scriptlocal_funcname(*p_opt);
+ if (name != NULL)
+ {
+ if (new_value_alloced)
+ free_string_option(*p_opt);
+ *p_opt = name;
+ new_value_alloced = TRUE;
+ }
+ }
+
+# ifdef FEAT_FOLDING
+ if (varp == &curwin->w_p_fde && foldmethodIsExpr(curwin))
+ foldUpdateAll(curwin);
+# endif
+ }
+#endif
+
#ifdef FEAT_COMPL_FUNC
// 'completefunc'
else if (gvarp == &p_cfu)
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index 9338fe0503..d4c44ce376 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -681,8 +681,19 @@ func Test_diffexpr()
set diffexpr=NewDiffFunc()
call assert_fails('windo diffthis', ['E117:', 'E97:'])
diffoff!
+
+ " Using a script-local function
+ func s:NewDiffExpr()
+ endfunc
+ set diffexpr=s:NewDiffExpr()
+ call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
+ set diffexpr=<SID>NewDiffExpr()
+ call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
+
%bwipe!
set diffexpr& diffopt&
+ delfunc DiffExpr
+ delfunc s:NewDiffExpr
endfunc
func Test_diffpatch()
@@ -1216,10 +1227,19 @@ func Test_patchexpr()
call assert_equal(2, winnr('$'))
call assert_true(&diff)
+ " Using a script-local function
+ func s:NewPatchExpr()
+ endfunc
+ set patchexpr=s:NewPatchExpr()
+ call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
+ set patchexpr=<SID>NewPatchExpr()
+ call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
+
call delete('Xinput')
call delete('Xdiff')
set patchexpr&
delfunc TPatch
+ delfunc s:NewPatchExpr
%bwipe!
endfunc
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index 46a475221f..c39c8a0fb1 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -324,6 +324,16 @@ func Test_edit_11_indentexpr()
set cinkeys&vim indentkeys&vim
set nocindent indentexpr=
delfu Do_Indent
+
+ " Using a script-local function
+ func s:NewIndentExpr()
+ endfunc
+ set indentexpr=s:NewIndentExpr()
+ call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+ set indentexpr=<SID>NewIndentExpr()
+ call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+ set indentexpr&
+
bw!
endfunc
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index 85fa43da3d..d35b7c807b 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -1382,4 +1382,30 @@ func Test_fold_jump()
bw!
endfunc
+" Test for using a script-local function for 'foldexpr'
+func Test_foldexpr_scriptlocal_func()
+ func! s:FoldFunc()
+ let g:FoldLnum = v:lnum
+ endfunc
+ new | only
+ call setline(1, 'abc')
+ let g:FoldLnum = 0
+ set foldmethod=expr foldexpr=s:FoldFunc()
+ redraw!
+ call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
+ call assert_equal(1, g:FoldLnum)
+ set foldmethod& foldexpr=
+ bw!
+ new | only
+ call setline(1, 'abc')
+ let g:FoldLnum = 0
+ set foldmethod=expr foldexpr=<SID>FoldFunc()
+ redraw!
+ call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
+ call assert_equal(1, g:FoldLnum)
+ set foldmethod& foldexpr=
+ delfunc s:FoldFunc
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_gf.vim b/src/testdir/test_gf.vim
index 5e5de415b4..1b13c42cd9 100644
--- a/src/testdir/test_gf.vim
+++ b/src/testdir/test_gf.vim
@@ -217,4 +217,30 @@ func Test_gf_includeexpr()
delfunc IncFunc
endfunc
+" Test for using a script-local function for 'includeexpr'
+func Test_includeexpr_scriptlocal_func()
+ func! s:IncludeFunc()
+ let g:IncludeFname = v:fname
+ return ''
+ endfunc
+ set includeexpr=s:IncludeFunc()
+ call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+ new | only
+ call setline(1, 'TestFile1')
+ let g:IncludeFname = ''
+ call assert_fails('normal! gf', 'E447:')
+ call assert_equal('TestFile1', g:IncludeFname)
+ bw!
+ set includeexpr=<SID>IncludeFunc()
+ call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+ new | only
+ call setline(1, 'TestFile2')
+ let g:IncludeFname = ''
+ call assert_fails('normal! gf', 'E447:')
+ call assert_equal('TestFile2', g:IncludeFname)
+ set includeexpr&
+ delfunc s:IncludeFunc
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim
index 133298db3a..90552843d1 100644
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -258,6 +258,15 @@ func Test_set_balloonexpr()
setl balloonexpr&
call assert_equal('', &balloonexpr)
delfunc MyBalloonExpr
+
+ " Using a script-local function
+ func s:NewBalloonExpr()
+ endfunc
+ set balloonexpr=s:NewBalloonExpr()
+ call assert_equal(expand('<SID>') .. 'NewBalloonExpr()', &balloonexpr)
+ set balloonexpr=<SID>NewBalloonExpr()
+ call assert_equal(expand('<SID>') .. 'NewBalloonExpr()', &balloonexpr)
+ delfunc s:NewBalloonExpr
bwipe!
" Multiline support
diff --git a/src/testdir/test_hardcopy.vim b/src/testdir/test_hardcopy.vim
index e390bd5cc8..be83728b4f 100644
--- a/src/testdir/test_hardcopy.vim
+++ b/src/testdir/test_hardcopy.vim
@@ -125,6 +125,14 @@ func Test_printexpr()
set printexpr=PrintFails(v:fname_in)
call assert_fails('hardcopy', 'E365:')
+ " Using a script-local function
+ func s:NewPrintExpr()
+ endfunc
+ set printexpr=s:NewPrintExpr()
+ call assert_equal(expand('<SID>') .. 'NewPrintExpr()', &printexpr)
+ set printexpr=<SID>NewPrintExpr()
+ call assert_equal(expand('<SID>') .. 'NewPrintExpr()', &printexpr)
+
set printexpr&
bwipe
endfunc
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 57ea6d3ecc..6458a1bed4 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -253,6 +253,45 @@ func Test_normal_formatexpr_returns_nonzero()
close!
endfunc
+" Test for using a script-local function for 'formatexpr'
+func Test_formatexpr_scriptlocal_func()
+ func! s:Format()
+ let g:FormatArgs = [v:lnum, v:count]
+ endfunc
+ set formatexpr=s:Format()
+ call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 2GVjgq
+ call assert_equal([2, 2], g:FormatArgs)
+ bw!
+ set formatexpr=<SID>Format()
+ call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 4GVjgq
+ call assert_equal([4, 2], g:FormatArgs)
+ bw!
+ let &formatexpr = 's:Format()'
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 6GVjgq
+ call assert_equal([6, 2], g:FormatArgs)
+ bw!
+ let &formatexpr = '<SID>Format()'
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 8GVjgq
+ call assert_equal([8, 2], g:FormatArgs)
+ setlocal formatexpr=
+ delfunc s:Format
+ bw!
+endfunc
+
" basic test for formatprg
func Test_normal06_formatprg()
" only test on non windows platform
diff --git a/src/version.c b/src/version.c
index 260182bdf7..1ada85606a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3900,
+/**/
3899,
/**/
3898,