To: vim_dev@googlegroups.com Subject: Patch 8.2.3900 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3900 Problem: It is not easy to use a script-local function for an option. Solution: recognize s: and at the start of the expression. (Yegappan Lakshmanan, closes #9401) Files: runtime/doc/diff.txt, runtime/doc/fold.txt, runtime/doc/options.txt, runtime/doc/print.txt, src/optionstr.c, src/testdir/test_diffmode.vim, src/testdir/test_edit.vim, src/testdir/test_fold.vim, src/testdir/test_gf.vim, src/testdir/test_gui.vim, src/testdir/test_hardcopy.vim, src/testdir/test_normal.vim *** ../vim-8.2.3899/runtime/doc/diff.txt 2021-02-10 12:18:14.067747045 +0000 --- runtime/doc/diff.txt 2021-12-26 10:47:20.315439073 +0000 *************** *** 396,401 **** --- 398,408 ---- The `redraw!` command may not be needed, depending on whether executing a shell command shows something on the display or not. + If the 'diffexpr' expression starts with s: or ||, then it is replaced + with the script ID (|local-function|). Example: > + set diffexpr=s:MyDiffExpr() + set diffexpr=SomeDiffExpr() + < *E810* *E97* Vim will do a test if the diff output looks alright. If it doesn't, you will get an error message. Possible causes: *************** *** 447,450 **** --- 454,462 ---- directory are accidentally patched. Vim will also delete files starting with v:fname_in and ending in ".rej" and ".orig". + If the 'patchexpr' expression starts with s: or ||, then it is replaced + with the script ID (|local-function|). Example: > + set patchexpr=s:MyPatchExpr() + set patchexpr=SomePatchExpr() + < vim:tw=78:ts=8:noet:ft=help:norl: *** ../vim-8.2.3899/runtime/doc/fold.txt 2019-12-12 11:49:05.000000000 +0000 --- runtime/doc/fold.txt 2021-12-26 10:47:20.315439073 +0000 *************** *** 121,126 **** --- 121,131 ---- Try to avoid the "=", "a" and "s" return values, since Vim often has to search backwards for a line for which the fold level is defined. This can be slow. + If the 'foldexpr' expression starts with s: or ||, then it is replaced + with the script ID (|local-function|). Example: > + set foldexpr=s:MyFoldExpr() + set foldexpr=SomeFoldExpr() + < An example of using "a1" and "s1": For a multi-line C comment, a line containing "/*" would return "a1" to start a fold, and a line containing "*/" would return "s1" to end the fold after that line: > *************** *** 541,546 **** --- 546,553 ---- A closed fold is indicated with a '+'. + These characters can be changed with the 'fillchars' option. + Where the fold column is too narrow to display all nested folds, digits are shown to indicate the nesting level. *** ../vim-8.2.3899/runtime/doc/options.txt 2021-12-22 19:44:55.474555117 +0000 --- runtime/doc/options.txt 2021-12-26 10:47:20.319439069 +0000 *************** *** 1225,1230 **** --- 1225,1235 ---- Vim does not try to send a message to an external debugger (Netbeans or Sun Workshop). + If the expression starts with s: or ||, then it is replaced with + the script ID (|local-function|). Example: > + set bexpr=s:MyBalloonExpr() + set bexpr=SomeBalloonExpr() + < The expression will be evaluated in the |sandbox| when set from a modeline, see |sandbox-option|. This option cannot be set in a modeline when 'modelineexpr' is off. *************** *** 3596,3601 **** --- 3607,3617 ---- When the expression evaluates to non-zero Vim will fall back to using the internal format mechanism. + If the expression starts with s: or ||, then it is replaced with + the script ID (|local-function|). Example: > + set formatexpr=s:MyFormatExpr() + set formatexpr=SomeFormatExpr() + < The expression will be evaluated in the |sandbox| when set from a modeline, see |sandbox-option|. That stops the option from working, since changing the buffer text is not allowed. *************** *** 4438,4443 **** --- 4454,4464 ---- found. Allows doing "gf" on the name after an 'include' statement. Also used for ||. + If the expression starts with s: or ||, then it is replaced with + the script ID (|local-function|). Example: > + set includeexpr=s:MyIncludeExpr(v:fname) + set includeexpr=SomeIncludeExpr(v:fname) + < The expression will be evaluated in the |sandbox| when set from a modeline, see |sandbox-option|. This option cannot be set in a modeline when 'modelineexpr' is off. *************** *** 4511,4516 **** --- 4532,4542 ---- The expression is evaluated with |v:lnum| set to the line number for which the indent is to be computed. The cursor is also in this line when the expression is evaluated (but it may be moved around). + If the expression starts with s: or ||, then it is replaced with + the script ID (|local-function|). Example: > + set indentexpr=s:MyIndentExpr() + set indentexpr=SomeIndentExpr() + < The expression must return the number of spaces worth of indent. It can return "-1" to keep the current indent (this means 'autoindent' is used for the indent). *** ../vim-8.2.3899/runtime/doc/print.txt 2021-01-31 16:02:06.258490157 +0000 --- runtime/doc/print.txt 2021-12-26 10:47:20.319439069 +0000 *************** *** 174,179 **** --- 174,184 ---- value for non-MS-Windows a trick is used: Adding "v:shell_error" will result in a non-zero number when the system() call fails. + If the expression starts with s: or ||, then it is replaced with the + script ID (|local-function|). Example: > + set printexpr=s:MyPrintFile() + set printexpr=SomePrintFile() + < This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. *** ../vim-8.2.3899/src/optionstr.c 2021-12-04 14:02:25.457024636 +0000 --- src/optionstr.c 2021-12-26 10:47:20.319439069 +0000 *************** *** 2026,2039 **** 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) { --- 2026,2031 ---- *************** *** 2307,2312 **** --- 2299,2387 ---- # 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 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) *** ../vim-8.2.3899/src/testdir/test_diffmode.vim 2021-11-21 11:35:59.456938797 +0000 --- src/testdir/test_diffmode.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 681,688 **** --- 681,699 ---- 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('') .. 'NewDiffExpr()', &diffexpr) + set diffexpr=NewDiffExpr() + call assert_equal(expand('') .. 'NewDiffExpr()', &diffexpr) + %bwipe! set diffexpr& diffopt& + delfunc DiffExpr + delfunc s:NewDiffExpr endfunc func Test_diffpatch() *************** *** 1216,1225 **** --- 1227,1245 ---- 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('') .. 'NewPatchExpr()', &patchexpr) + set patchexpr=NewPatchExpr() + call assert_equal(expand('') .. 'NewPatchExpr()', &patchexpr) + call delete('Xinput') call delete('Xdiff') set patchexpr& delfunc TPatch + delfunc s:NewPatchExpr %bwipe! endfunc *** ../vim-8.2.3899/src/testdir/test_edit.vim 2021-12-16 14:45:09.365563190 +0000 --- src/testdir/test_edit.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 324,329 **** --- 324,339 ---- 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('') .. 'NewIndentExpr()', &indentexpr) + set indentexpr=NewIndentExpr() + call assert_equal(expand('') .. 'NewIndentExpr()', &indentexpr) + set indentexpr& + bw! endfunc *** ../vim-8.2.3899/src/testdir/test_fold.vim 2021-04-05 11:47:21.146578067 +0100 --- src/testdir/test_fold.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 1382,1385 **** --- 1382,1411 ---- 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('') .. '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=FoldFunc() + redraw! + call assert_equal(expand('') .. 'FoldFunc()', &foldexpr) + call assert_equal(1, g:FoldLnum) + set foldmethod& foldexpr= + delfunc s:FoldFunc + bw! + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3899/src/testdir/test_gf.vim 2020-10-04 15:16:50.919838655 +0100 --- src/testdir/test_gf.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 217,220 **** --- 217,246 ---- 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('') .. '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=IncludeFunc() + call assert_equal(expand('') .. '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 *** ../vim-8.2.3899/src/testdir/test_gui.vim 2021-10-20 23:08:07.790623217 +0100 --- src/testdir/test_gui.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 258,263 **** --- 258,272 ---- 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('') .. 'NewBalloonExpr()', &balloonexpr) + set balloonexpr=NewBalloonExpr() + call assert_equal(expand('') .. 'NewBalloonExpr()', &balloonexpr) + delfunc s:NewBalloonExpr bwipe! " Multiline support *** ../vim-8.2.3899/src/testdir/test_hardcopy.vim 2021-01-01 20:34:33.323754984 +0000 --- src/testdir/test_hardcopy.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 125,130 **** --- 125,138 ---- 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('') .. 'NewPrintExpr()', &printexpr) + set printexpr=NewPrintExpr() + call assert_equal(expand('') .. 'NewPrintExpr()', &printexpr) + set printexpr& bwipe endfunc *** ../vim-8.2.3899/src/testdir/test_normal.vim 2021-12-24 20:47:34.748104242 +0000 --- src/testdir/test_normal.vim 2021-12-26 10:47:20.319439069 +0000 *************** *** 253,258 **** --- 253,297 ---- 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('') .. '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=Format() + call assert_equal(expand('') .. '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 = '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 *** ../vim-8.2.3899/src/version.c 2021-12-25 22:10:38.817746251 +0000 --- src/version.c 2021-12-26 10:50:03.207224013 +0000 *************** *** 751,752 **** --- 751,754 ---- { /* Add new patch number below this line */ + /**/ + 3900, /**/ -- hundred-and-one symptoms of being an internet addict: 110. You actually volunteer to become your employer's webmaster. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///