0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 9.0.1243: :setglobal cannot use script-local function for "expr" option

Problem:    :setglobal cannot use script-local function for "expr" option.
Solution:   Use the pointer to the option value properly. (closes #11883)
This commit is contained in:
zeertzjq
2023-01-25 15:31:28 +00:00
committed by Bram Moolenaar
parent b0d45ec67f
commit 01d4efe2e8
6 changed files with 149 additions and 48 deletions

View File

@@ -2311,8 +2311,8 @@ did_set_string_option(
varp == &p_dex || varp == &p_dex ||
# endif # endif
# ifdef FEAT_FOLDING # ifdef FEAT_FOLDING
varp == &curwin->w_p_fde || gvarp == &curwin->w_allbuf_opt.wo_fde ||
varp == &curwin->w_p_fdt || gvarp == &curwin->w_allbuf_opt.wo_fdt ||
# endif # endif
gvarp == &p_fex || gvarp == &p_fex ||
# ifdef FEAT_FIND_ID # ifdef FEAT_FIND_ID
@@ -2327,52 +2327,13 @@ did_set_string_option(
# endif # endif
varp == &p_ccv) varp == &p_ccv)
{ {
char_u **p_opt = NULL;
char_u *name;
// If the option value starts with <SID> or s:, then replace that with // If the option value starts with <SID> or s:, then replace that with
// the script identifier. // the script identifier.
# ifdef FEAT_BEVAL char_u *name = get_scriptlocal_funcname(*varp);
if (varp == &p_bexpr) // 'balloonexpr' if (name != NULL)
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;
if (varp == &curwin->w_p_fdt) // 'foldtext'
p_opt = &curwin->w_p_fdt;
# 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
if (gvarp == &p_inde) // 'indentexpr'
p_opt = &curbuf->b_p_inde;
# 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 (varp == &p_ccv) // 'charconvert'
p_opt = &p_ccv;
if (p_opt != NULL)
{ {
name = get_scriptlocal_funcname(*p_opt); free_string_option(*varp);
if (name != NULL) *varp = name;
{
free_string_option(*p_opt);
*p_opt = name;
}
} }
# ifdef FEAT_FOLDING # ifdef FEAT_FOLDING

View File

@@ -330,8 +330,23 @@ func Test_edit_11_indentexpr()
endfunc endfunc
set indentexpr=s:NewIndentExpr() set indentexpr=s:NewIndentExpr()
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
set indentexpr=<SID>NewIndentExpr() set indentexpr=<SID>NewIndentExpr()
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
setlocal indentexpr=
setglobal indentexpr=s:NewIndentExpr()
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
call assert_equal('', &indentexpr)
new
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
bw!
setglobal indentexpr=<SID>NewIndentExpr()
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
call assert_equal('', &indentexpr)
new
call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
bw!
set indentexpr& set indentexpr&
bw! bw!

View File

@@ -1503,6 +1503,7 @@ func Test_foldexpr_scriptlocal_func()
set foldmethod=expr foldexpr=s:FoldFunc() set foldmethod=expr foldexpr=s:FoldFunc()
redraw! redraw!
call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr) call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
call assert_equal(1, g:FoldLnum) call assert_equal(1, g:FoldLnum)
set foldmethod& foldexpr= set foldmethod& foldexpr=
bw! bw!
@@ -1512,8 +1513,31 @@ func Test_foldexpr_scriptlocal_func()
set foldmethod=expr foldexpr=<SID>FoldFunc() set foldmethod=expr foldexpr=<SID>FoldFunc()
redraw! redraw!
call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr) call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
call assert_equal(1, g:FoldLnum) call assert_equal(1, g:FoldLnum)
set foldmethod& foldexpr= bw!
call setline(1, 'abc')
setlocal foldmethod& foldexpr&
setglobal foldmethod=expr foldexpr=s:FoldFunc()
call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
call assert_equal('0', &foldexpr)
enew!
call setline(1, 'abc')
redraw!
call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
call assert_equal(1, g:FoldLnum)
bw!
call setline(1, 'abc')
setlocal foldmethod& foldexpr&
setglobal foldmethod=expr foldexpr=<SID>FoldFunc()
call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
call assert_equal('0', &foldexpr)
enew!
call setline(1, 'abc')
redraw!
call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
call assert_equal(1, g:FoldLnum)
set foldmethod& foldexpr&
delfunc s:FoldFunc delfunc s:FoldFunc
bw! bw!
endfunc endfunc
@@ -1527,25 +1551,53 @@ func Test_foldtext_scriptlocal_func()
new | only new | only
call setline(1, range(50)) call setline(1, range(50))
let g:FoldTextArgs = [] let g:FoldTextArgs = []
set foldmethod=manual
set foldtext=s:FoldText() set foldtext=s:FoldText()
norm! 4Gzf4j norm! 4Gzf4j
redraw! redraw!
call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext) call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
call assert_equal([4, 8], g:FoldTextArgs) call assert_equal([4, 8], g:FoldTextArgs)
set foldtext& set foldtext&
bw! bw!
new | only new | only
call setline(1, range(50)) call setline(1, range(50))
let g:FoldTextArgs = [] let g:FoldTextArgs = []
set foldmethod=manual
set foldtext=<SID>FoldText() set foldtext=<SID>FoldText()
norm! 8Gzf4j norm! 8Gzf4j
redraw! redraw!
call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext) call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
call assert_equal([8, 12], g:FoldTextArgs) call assert_equal([8, 12], g:FoldTextArgs)
set foldtext& set foldtext&
bw! bw!
call setline(1, range(50))
let g:FoldTextArgs = []
setlocal foldtext&
setglobal foldtext=s:FoldText()
call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
call assert_equal('foldtext()', &foldtext)
enew!
call setline(1, range(50))
norm! 12Gzf4j
redraw!
call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
call assert_equal([12, 16], g:FoldTextArgs)
set foldtext&
bw!
call setline(1, range(50))
let g:FoldTextArgs = []
setlocal foldtext&
setglobal foldtext=<SID>FoldText()
call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
call assert_equal('foldtext()', &foldtext)
enew!
call setline(1, range(50))
norm! 16Gzf4j
redraw!
call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
call assert_equal([16, 20], g:FoldTextArgs)
set foldtext&
bw!
delfunc s:FoldText delfunc s:FoldText
endfunc endfunc

View File

@@ -227,6 +227,7 @@ func Test_includeexpr_scriptlocal_func()
endfunc endfunc
set includeexpr=s:IncludeFunc() set includeexpr=s:IncludeFunc()
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr) call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
new | only new | only
call setline(1, 'TestFile1') call setline(1, 'TestFile1')
let g:IncludeFname = '' let g:IncludeFname = ''
@@ -235,11 +236,35 @@ func Test_includeexpr_scriptlocal_func()
bw! bw!
set includeexpr=<SID>IncludeFunc() set includeexpr=<SID>IncludeFunc()
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr) call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
new | only new | only
call setline(1, 'TestFile2') call setline(1, 'TestFile2')
let g:IncludeFname = '' let g:IncludeFname = ''
call assert_fails('normal! gf', 'E447:') call assert_fails('normal! gf', 'E447:')
call assert_equal('TestFile2', g:IncludeFname) call assert_equal('TestFile2', g:IncludeFname)
bw!
setlocal includeexpr=
setglobal includeexpr=s:IncludeFunc()
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
call assert_equal('', &includeexpr)
new
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
call setline(1, 'TestFile3')
let g:IncludeFname = ''
call assert_fails('normal! gf', 'E447:')
call assert_equal('TestFile3', g:IncludeFname)
bw!
setlocal includeexpr=
setglobal includeexpr=<SID>IncludeFunc()
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
call assert_equal('', &includeexpr)
new
call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
call setline(1, 'TestFile4')
let g:IncludeFname = ''
call assert_fails('normal! gf', 'E447:')
call assert_equal('TestFile4', g:IncludeFname)
bw!
set includeexpr& set includeexpr&
delfunc s:IncludeFunc delfunc s:IncludeFunc
bw! bw!

View File

@@ -262,6 +262,7 @@ func Test_formatexpr_scriptlocal_func()
endfunc endfunc
set formatexpr=s:Format() set formatexpr=s:Format()
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr) call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
new | only new | only
call setline(1, range(1, 40)) call setline(1, range(1, 40))
let g:FormatArgs = [] let g:FormatArgs = []
@@ -270,6 +271,7 @@ func Test_formatexpr_scriptlocal_func()
bw! bw!
set formatexpr=<SID>Format() set formatexpr=<SID>Format()
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr) call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
new | only new | only
call setline(1, range(1, 40)) call setline(1, range(1, 40))
let g:FormatArgs = [] let g:FormatArgs = []
@@ -277,6 +279,7 @@ func Test_formatexpr_scriptlocal_func()
call assert_equal([4, 2], g:FormatArgs) call assert_equal([4, 2], g:FormatArgs)
bw! bw!
let &formatexpr = 's:Format()' let &formatexpr = 's:Format()'
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
new | only new | only
call setline(1, range(1, 40)) call setline(1, range(1, 40))
let g:FormatArgs = [] let g:FormatArgs = []
@@ -284,12 +287,55 @@ func Test_formatexpr_scriptlocal_func()
call assert_equal([6, 2], g:FormatArgs) call assert_equal([6, 2], g:FormatArgs)
bw! bw!
let &formatexpr = '<SID>Format()' let &formatexpr = '<SID>Format()'
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
new | only new | only
call setline(1, range(1, 40)) call setline(1, range(1, 40))
let g:FormatArgs = [] let g:FormatArgs = []
normal! 8GVjgq normal! 8GVjgq
call assert_equal([8, 2], g:FormatArgs) call assert_equal([8, 2], g:FormatArgs)
bw!
setlocal formatexpr= setlocal formatexpr=
setglobal formatexpr=s:Format()
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
call assert_equal('', &formatexpr)
new
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call setline(1, range(1, 40))
let g:FormatArgs = []
normal! 10GVjgq
call assert_equal([10, 2], g:FormatArgs)
bw!
setglobal formatexpr=<SID>Format()
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
call assert_equal('', &formatexpr)
new
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call setline(1, range(1, 40))
let g:FormatArgs = []
normal! 12GVjgq
call assert_equal([12, 2], g:FormatArgs)
bw!
let &g:formatexpr = 's:Format()'
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
call assert_equal('', &formatexpr)
new
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call setline(1, range(1, 40))
let g:FormatArgs = []
normal! 14GVjgq
call assert_equal([14, 2], g:FormatArgs)
bw!
let &g:formatexpr = '<SID>Format()'
call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
call assert_equal('', &formatexpr)
new
call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
call setline(1, range(1, 40))
let g:FormatArgs = []
normal! 16GVjgq
call assert_equal([16, 2], g:FormatArgs)
bw!
set formatexpr=
delfunc s:Format delfunc s:Format
bw! bw!
endfunc endfunc

View File

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