0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 8.2.3900: it is not easy to use a script-local function for an option

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)
This commit is contained in:
Yegappan Lakshmanan
2021-12-26 10:51:39 +00:00
committed by Bram Moolenaar
parent ec86520f94
commit 8bb65f230d
13 changed files with 265 additions and 8 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -749,6 +749,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3900,
/**/
3899,
/**/