# HG changeset patch # User Bram Moolenaar # Date 1604247306 -3600 # Node ID 82a7aff951d2656699ff37dda999fe3f7fae25df # Parent 84263588f5bea6ee3f60c9610e621d5c5f63d2c8 patch 8.2.1934: Vim9: command modifiers in :def function not tested Commit: https://github.com/vim/vim/commit/e88c8e802cf5ee59a2a6649a5b46c9e80de823ad Author: Bram Moolenaar Date: Sun Nov 1 17:03:37 2020 +0100 patch 8.2.1934: Vim9: command modifiers in :def function not tested Problem: Vim9: command modifiers in :def function not tested. Solution: Add tests. Fix using modifier before filter command. diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1782,14 +1782,27 @@ do_one_cmd( */ cmd = ea.cmd; #ifdef FEAT_EVAL - // In Vim9 script a colon is required before the range. - may_have_range = !vim9script || starts_with_colon; + // In Vim9 script a colon is required before the range. This may also be + // after command modifiers. + if (vim9script) + { + may_have_range = FALSE; + for (p = ea.cmd; p >= *cmdlinep; --p) + { + if (*p == ':') + may_have_range = TRUE; + if (p < ea.cmd && !VIM_ISWHITE(*p)) + break; + } + } + else + may_have_range = TRUE; if (may_have_range) #endif ea.cmd = skip_range(ea.cmd, TRUE, NULL); #ifdef FEAT_EVAL - if (vim9script && !starts_with_colon) + if (vim9script && !may_have_range) { if (ea.cmd == cmd + 1 && *cmd == '$') // should be "$VAR = val" diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -2,6 +2,7 @@ source check.vim source vim9.vim +source term_util.vim source view_util.vim def Test_edit_wildcards() @@ -312,7 +313,7 @@ def Test_filter_is_not_modifier() assert_equal([#{x: 3, y: 4}], tags) enddef -def Test_filter_is_recognized() +def Test_command_modifier_filter() var lines =<< trim END final expected = "\nType Name Content\n c \"c piyo" @a = 'hoge' @@ -324,6 +325,135 @@ def Test_filter_is_recognized() CheckDefAndScriptSuccess(lines) enddef +def Test_win_command_modifiers() + assert_equal(1, winnr('$')) + + set splitright + vsplit + assert_equal(2, winnr()) + close + aboveleft vsplit + assert_equal(1, winnr()) + close + set splitright& + + vsplit + assert_equal(1, winnr()) + close + belowright vsplit + assert_equal(2, winnr()) + close + rightbelow vsplit + assert_equal(2, winnr()) + close + + browse set + assert_equal('option-window', expand('%')) + close + + vsplit + botright split + assert_equal(3, winnr()) + assert_equal(&columns, winwidth(0)) + close + close + + vsplit + topleft split + assert_equal(1, winnr()) + assert_equal(&columns, winwidth(0)) + close + close + + gettabinfo()->len()->assert_equal(1) + tab split + gettabinfo()->len()->assert_equal(2) + tabclose + + vertical new + assert_inrange(&columns / 2 - 2, &columns / 2 + 1, winwidth(0)) + close +enddef + +func Test_command_modifier_confirm() + CheckNotGui + CheckRunVimInTerminal + + " Test for saving all the modified buffers + let lines =<< trim END + call setline(1, 'changed') + def Getout() + confirm write Xfile + enddef + END + call writefile(lines, 'Xconfirmscript') + call writefile(['empty'], 'Xfile') + let buf = RunVimInTerminal('-S Xconfirmscript', {'rows': 8}) + call term_sendkeys(buf, ":call Getout()\n") + call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000) + call term_sendkeys(buf, "y") + call StopVimInTerminal(buf) + + call assert_equal(['changed'], readfile('Xfile')) + call delete('Xfile') + call delete('Xconfirmscript') +endfunc + +def Test_command_modifiers_keep() + if has('unix') + def DoTest(addRflag: bool, keepMarks: bool, hasMarks: bool) + new + setline(1, ['one', 'two', 'three']) + normal 1Gma + normal 2Gmb + normal 3Gmc + if addRflag + set cpo+=R + else + set cpo-=R + endif + if keepMarks + keepmarks :%!cat + else + :%!cat + endif + if hasMarks + assert_equal(1, line("'a")) + assert_equal(2, line("'b")) + assert_equal(3, line("'c")) + else + assert_equal(0, line("'a")) + assert_equal(0, line("'b")) + assert_equal(0, line("'c")) + endif + quit! + enddef + DoTest(false, false, true) + DoTest(true, false, false) + DoTest(false, true, true) + DoTest(true, true, true) + set cpo&vim + endif + + # TODO + # lockmarks + # keepalt + # keeppatterns + # keepjumps +enddef + +def Test_command_modifier_other() + # TODO + # hide + # noautocmd + # noswapfile + # sandbox + # silent + # silent! + # unsilent + # verbose +enddef + def Test_eval_command() var from = 3 var to = 5 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1934, +/**/ 1933, /**/ 1932, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2642,6 +2642,7 @@ compile_call( type_T *type = ((type_T **)stack->ga_data)[ stack->ga_len - 2]; + // add() can be compiled to instructions if we know the type if (type->tt_type == VAR_LIST) { // inline "add(list, item)" so that the type can be checked @@ -7173,10 +7174,6 @@ compile_def_function(ufunc_T *ufunc, int continue; } break; - - case ':': - starts_with_colon = TRUE; - break; } /* @@ -7195,6 +7192,16 @@ compile_def_function(ufunc_T *ufunc, int generate_cmdmods(&cctx, &local_cmdmod); undo_cmdmod(&local_cmdmod); + // Check if there was a colon after the last command modifier or before + // the current position. + for (p = ea.cmd; p >= line; --p) + { + if (*p == ':') + starts_with_colon = TRUE; + if (p < ea.cmd && !VIM_ISWHITE(*p)) + break; + } + // Skip ":call" to get to the function name. p = ea.cmd; if (checkforcmd(&ea.cmd, "call", 3))