# HG changeset patch # User Bram Moolenaar # Date 1674661503 -3600 # Node ID 5614e76f3dee23b6f20a44bb99dc0481b90244a5 # Parent 08ee50169c0fd921063f0148262b04ef1f6992a5 patch 9.0.1243: :setglobal cannot use script-local function for "expr" option Commit: https://github.com/vim/vim/commit/01d4efe2e87632aa085897d3d64e27585908f977 Author: zeertzjq Date: Wed Jan 25 15:31:28 2023 +0000 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 https://github.com/vim/vim/issues/11883) diff --git a/src/optionstr.c b/src/optionstr.c --- a/src/optionstr.c +++ b/src/optionstr.c @@ -2311,8 +2311,8 @@ did_set_string_option( varp == &p_dex || # endif # ifdef FEAT_FOLDING - varp == &curwin->w_p_fde || - varp == &curwin->w_p_fdt || + gvarp == &curwin->w_allbuf_opt.wo_fde || + gvarp == &curwin->w_allbuf_opt.wo_fdt || # endif gvarp == &p_fex || # ifdef FEAT_FIND_ID @@ -2327,52 +2327,13 @@ did_set_string_option( # endif varp == &p_ccv) { - char_u **p_opt = NULL; - char_u *name; - // If the option value starts with 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; - 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) + char_u *name = get_scriptlocal_funcname(*varp); + if (name != NULL) { - name = get_scriptlocal_funcname(*p_opt); - if (name != NULL) - { - free_string_option(*p_opt); - *p_opt = name; - } + free_string_option(*varp); + *varp = name; } # ifdef FEAT_FOLDING diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -330,8 +330,23 @@ func Test_edit_11_indentexpr() endfunc set indentexpr=s:NewIndentExpr() call assert_equal(expand('') .. 'NewIndentExpr()', &indentexpr) + call assert_equal(expand('') .. 'NewIndentExpr()', &g:indentexpr) set indentexpr=NewIndentExpr() call assert_equal(expand('') .. 'NewIndentExpr()', &indentexpr) + call assert_equal(expand('') .. 'NewIndentExpr()', &g:indentexpr) + setlocal indentexpr= + setglobal indentexpr=s:NewIndentExpr() + call assert_equal(expand('') .. 'NewIndentExpr()', &g:indentexpr) + call assert_equal('', &indentexpr) + new + call assert_equal(expand('') .. 'NewIndentExpr()', &indentexpr) + bw! + setglobal indentexpr=NewIndentExpr() + call assert_equal(expand('') .. 'NewIndentExpr()', &g:indentexpr) + call assert_equal('', &indentexpr) + new + call assert_equal(expand('') .. 'NewIndentExpr()', &indentexpr) + bw! set indentexpr& bw! diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim --- a/src/testdir/test_fold.vim +++ b/src/testdir/test_fold.vim @@ -1503,6 +1503,7 @@ func Test_foldexpr_scriptlocal_func() set foldmethod=expr foldexpr=s:FoldFunc() redraw! call assert_equal(expand('') .. 'FoldFunc()', &foldexpr) + call assert_equal(expand('') .. 'FoldFunc()', &g:foldexpr) call assert_equal(1, g:FoldLnum) set foldmethod& foldexpr= bw! @@ -1512,8 +1513,31 @@ func Test_foldexpr_scriptlocal_func() set foldmethod=expr foldexpr=FoldFunc() redraw! call assert_equal(expand('') .. 'FoldFunc()', &foldexpr) + call assert_equal(expand('') .. 'FoldFunc()', &g:foldexpr) 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('') .. 'FoldFunc()', &g:foldexpr) + call assert_equal('0', &foldexpr) + enew! + call setline(1, 'abc') + redraw! + call assert_equal(expand('') .. 'FoldFunc()', &foldexpr) + call assert_equal(1, g:FoldLnum) + bw! + call setline(1, 'abc') + setlocal foldmethod& foldexpr& + setglobal foldmethod=expr foldexpr=FoldFunc() + call assert_equal(expand('') .. 'FoldFunc()', &g:foldexpr) + call assert_equal('0', &foldexpr) + enew! + call setline(1, 'abc') + redraw! + call assert_equal(expand('') .. 'FoldFunc()', &foldexpr) + call assert_equal(1, g:FoldLnum) + set foldmethod& foldexpr& delfunc s:FoldFunc bw! endfunc @@ -1527,25 +1551,53 @@ func Test_foldtext_scriptlocal_func() new | only call setline(1, range(50)) let g:FoldTextArgs = [] - set foldmethod=manual set foldtext=s:FoldText() norm! 4Gzf4j redraw! call assert_equal(expand('') .. 'FoldText()', &foldtext) + call assert_equal(expand('') .. 'FoldText()', &g:foldtext) call assert_equal([4, 8], g:FoldTextArgs) set foldtext& bw! new | only call setline(1, range(50)) let g:FoldTextArgs = [] - set foldmethod=manual set foldtext=FoldText() norm! 8Gzf4j redraw! call assert_equal(expand('') .. 'FoldText()', &foldtext) + call assert_equal(expand('') .. 'FoldText()', &g:foldtext) call assert_equal([8, 12], g:FoldTextArgs) set foldtext& bw! + call setline(1, range(50)) + let g:FoldTextArgs = [] + setlocal foldtext& + setglobal foldtext=s:FoldText() + call assert_equal(expand('') .. 'FoldText()', &g:foldtext) + call assert_equal('foldtext()', &foldtext) + enew! + call setline(1, range(50)) + norm! 12Gzf4j + redraw! + call assert_equal(expand('') .. 'FoldText()', &foldtext) + call assert_equal([12, 16], g:FoldTextArgs) + set foldtext& + bw! + call setline(1, range(50)) + let g:FoldTextArgs = [] + setlocal foldtext& + setglobal foldtext=FoldText() + call assert_equal(expand('') .. 'FoldText()', &g:foldtext) + call assert_equal('foldtext()', &foldtext) + enew! + call setline(1, range(50)) + norm! 16Gzf4j + redraw! + call assert_equal(expand('') .. 'FoldText()', &foldtext) + call assert_equal([16, 20], g:FoldTextArgs) + set foldtext& + bw! delfunc s:FoldText endfunc diff --git a/src/testdir/test_gf.vim b/src/testdir/test_gf.vim --- a/src/testdir/test_gf.vim +++ b/src/testdir/test_gf.vim @@ -227,6 +227,7 @@ func Test_includeexpr_scriptlocal_func() endfunc set includeexpr=s:IncludeFunc() call assert_equal(expand('') .. 'IncludeFunc()', &includeexpr) + call assert_equal(expand('') .. 'IncludeFunc()', &g:includeexpr) new | only call setline(1, 'TestFile1') let g:IncludeFname = '' @@ -235,11 +236,35 @@ func Test_includeexpr_scriptlocal_func() bw! set includeexpr=IncludeFunc() call assert_equal(expand('') .. 'IncludeFunc()', &includeexpr) + call assert_equal(expand('') .. 'IncludeFunc()', &g:includeexpr) new | only call setline(1, 'TestFile2') let g:IncludeFname = '' call assert_fails('normal! gf', 'E447:') call assert_equal('TestFile2', g:IncludeFname) + bw! + setlocal includeexpr= + setglobal includeexpr=s:IncludeFunc() + call assert_equal(expand('') .. 'IncludeFunc()', &g:includeexpr) + call assert_equal('', &includeexpr) + new + call assert_equal(expand('') .. '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=IncludeFunc() + call assert_equal(expand('') .. 'IncludeFunc()', &g:includeexpr) + call assert_equal('', &includeexpr) + new + call assert_equal(expand('') .. 'IncludeFunc()', &includeexpr) + call setline(1, 'TestFile4') + let g:IncludeFname = '' + call assert_fails('normal! gf', 'E447:') + call assert_equal('TestFile4', g:IncludeFname) + bw! set includeexpr& delfunc s:IncludeFunc bw! diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -262,6 +262,7 @@ func Test_formatexpr_scriptlocal_func() endfunc set formatexpr=s:Format() call assert_equal(expand('') .. 'Format()', &formatexpr) + call assert_equal(expand('') .. 'Format()', &g:formatexpr) new | only call setline(1, range(1, 40)) let g:FormatArgs = [] @@ -270,6 +271,7 @@ func Test_formatexpr_scriptlocal_func() bw! set formatexpr=Format() call assert_equal(expand('') .. 'Format()', &formatexpr) + call assert_equal(expand('') .. 'Format()', &g:formatexpr) new | only call setline(1, range(1, 40)) let g:FormatArgs = [] @@ -277,6 +279,7 @@ func Test_formatexpr_scriptlocal_func() call assert_equal([4, 2], g:FormatArgs) bw! let &formatexpr = 's:Format()' + call assert_equal(expand('') .. 'Format()', &g:formatexpr) new | only call setline(1, range(1, 40)) let g:FormatArgs = [] @@ -284,12 +287,55 @@ func Test_formatexpr_scriptlocal_func() call assert_equal([6, 2], g:FormatArgs) bw! let &formatexpr = 'Format()' + call assert_equal(expand('') .. 'Format()', &g:formatexpr) new | only call setline(1, range(1, 40)) let g:FormatArgs = [] normal! 8GVjgq call assert_equal([8, 2], g:FormatArgs) + bw! setlocal formatexpr= + setglobal formatexpr=s:Format() + call assert_equal(expand('') .. 'Format()', &g:formatexpr) + call assert_equal('', &formatexpr) + new + call assert_equal(expand('') .. 'Format()', &formatexpr) + call setline(1, range(1, 40)) + let g:FormatArgs = [] + normal! 10GVjgq + call assert_equal([10, 2], g:FormatArgs) + bw! + setglobal formatexpr=Format() + call assert_equal(expand('') .. 'Format()', &g:formatexpr) + call assert_equal('', &formatexpr) + new + call assert_equal(expand('') .. '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('') .. 'Format()', &g:formatexpr) + call assert_equal('', &formatexpr) + new + call assert_equal(expand('') .. 'Format()', &formatexpr) + call setline(1, range(1, 40)) + let g:FormatArgs = [] + normal! 14GVjgq + call assert_equal([14, 2], g:FormatArgs) + bw! + let &g:formatexpr = 'Format()' + call assert_equal(expand('') .. 'Format()', &g:formatexpr) + call assert_equal('', &formatexpr) + new + call assert_equal(expand('') .. '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 bw! endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1243, +/**/ 1242, /**/ 1241,