From 7522f6982197f83a5c0f6e9af07fb713934f824a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 14:12:50 +0200 Subject: [PATCH 01/12] patch 7.4.2162 Problem: Result of getcompletion('', 'sign') depends on previous completion. Solution: Call set_context_in_sign_cmd(). (Dominique Pelle) --- src/evalfunc.c | 7 +++++++ src/testdir/test_cmdline.vim | 16 +++++++++++++--- src/version.c | 2 ++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/evalfunc.c b/src/evalfunc.c index dc0e630af8..3754534460 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -4247,6 +4247,13 @@ f_getcompletion(typval_T *argvars, typval_T *rettv) xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern); } #endif +#ifdef FEAT_SIGNS + if (xpc.xp_context == EXPAND_SIGN) + { + set_context_in_sign_cmd(&xpc, xpc.xp_pattern); + xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern); + } +#endif pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context); if ((rettv_list_alloc(rettv) != FAIL) && (pat != NULL)) diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 12194cd963..e2c1876934 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -138,6 +138,19 @@ func Test_getcompletion() call assert_equal(keys, l) endif + if has('signs') + sign define Testing linehl=Comment + let l = getcompletion('', 'sign') + let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace'] + call assert_equal(cmds, l) + " using cmdline completion must not change the result + call feedkeys(":sign list \\", 'xt') + let l = getcompletion('', 'sign') + call assert_equal(cmds, l) + let l = getcompletion('list ', 'sign') + call assert_equal(['Testing'], l) + endif + " For others test if the name is recognized. let names = ['buffer', 'environment', 'file_in_path', \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user'] @@ -150,9 +163,6 @@ func Test_getcompletion() if has('profile') call add(names, 'syntime') endif - if has('signs') - call add(names, 'sign') - endif set tags=Xtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags') diff --git a/src/version.c b/src/version.c index e68df1f5ac..bd2b16c7ab 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2162, /**/ 2161, /**/ From d76a0c15f8bdbc901015879177fd5076d34c7a06 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 15:29:22 +0200 Subject: [PATCH 02/12] patch 7.4.2163 Problem: match() and related functions tested with old style test. Solution: Convert to new style test. (Hirohito Higashi) --- src/Makefile | 4 +- src/testdir/Make_all.mak | 1 - src/testdir/test63.in | 200 ------------------------------- src/testdir/test63.ok | 17 --- src/testdir/test_alot.vim | 2 +- src/testdir/test_match.vim | 165 +++++++++++++++++++++++++ src/testdir/test_matchstrpos.vim | 13 -- src/version.c | 2 + 8 files changed, 170 insertions(+), 234 deletions(-) delete mode 100644 src/testdir/test63.in delete mode 100644 src/testdir/test63.ok create mode 100644 src/testdir/test_match.vim delete mode 100644 src/testdir/test_matchstrpos.vim diff --git a/src/Makefile b/src/Makefile index 3559659994..33d8b8c53c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2044,7 +2044,7 @@ test1 \ test30 test31 test32 test33 test34 test36 test37 test38 test39 \ test40 test41 test42 test43 test44 test45 test46 test48 test49 \ test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \ - test60 test62 test63 test64 test65 test66 test67 test68 test69 \ + test60 test62 test64 test65 test66 test67 test68 test69 \ test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \ test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \ test90 test91 test92 test93 test94 test95 test97 test98 test99 \ @@ -2095,9 +2095,9 @@ test_arglist \ test_largefile \ test_lispwords \ test_man \ + test_match \ test_matchadd_conceal \ test_matchadd_conceal_utf8 \ - test_matchstrpos \ test_menu \ test_messages \ test_netbeans \ diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 0ff00660ce..e7e4c680aa 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -51,7 +51,6 @@ SCRIPTS_ALL = \ test57.out \ test60.out \ test62.out \ - test63.out \ test64.out \ test65.out \ test66.out \ diff --git a/src/testdir/test63.in b/src/testdir/test63.in deleted file mode 100644 index 03b2197aaf..0000000000 --- a/src/testdir/test63.in +++ /dev/null @@ -1,200 +0,0 @@ -Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()", -"matchadd()", "matchaddpos", "matcharg()", "matchdelete()", and "setmatches()". - -STARTTEST -:so small.vim -:set encoding=utf8 -:" --- Check that "matcharg()" returns the correct group and pattern if a match -:" --- is defined. -:let @r = "*** Test 1: " -:highlight MyGroup1 term=bold ctermbg=red guibg=red -:highlight MyGroup2 term=italic ctermbg=green guibg=green -:highlight MyGroup3 term=underline ctermbg=blue guibg=blue -:match MyGroup1 /TODO/ -:2match MyGroup2 /FIXME/ -:3match MyGroup3 /XXX/ -:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX'] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:" --- Check that "matcharg()" returns an empty list if the argument is not 1, -:" --- 2 or 3 (only 0 and 4 are tested). -:let @r .= "*** Test 2: " -:if matcharg(0) == [] && matcharg(4) == [] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:" --- Check that "matcharg()" returns ['', ''] if a match is not defined. -:let @r .= "*** Test 3: " -:match -:2match -:3match -:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', ''] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:" --- Check that "matchadd()" and "getmatches()" agree on added matches and -:" --- that default values apply. -:let @r .= "*** Test 4: " -:let m1 = matchadd("MyGroup1", "TODO") -:let m2 = matchadd("MyGroup2", "FIXME", 42) -:let m3 = matchadd("MyGroup3", "XXX", 60, 17) -:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:" --- Check that "matchdelete()" deletes the matches defined in the previous -:" --- test correctly. -:let @r .= "*** Test 5: " -:call matchdelete(m1) -:call matchdelete(m2) -:call matchdelete(m3) -:unlet m1 -:unlet m2 -:unlet m3 -:if getmatches() == [] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1. -:let @r .= "*** Test 6: " -:let m = matchadd("MyGroup1", "TODO") -:let r1 = matchdelete(m) -:let r2 = matchdelete(42) -:if r1 == 0 && r2 == -1 -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:unlet m -:unlet r1 -:unlet r2 -:" --- Check that "clearmatches()" clears all matches defined by ":match" and -:" --- "matchadd()". -:let @r .= "*** Test 7: " -:let m1 = matchadd("MyGroup1", "TODO") -:let m2 = matchadd("MyGroup2", "FIXME", 42) -:let m3 = matchadd("MyGroup3", "XXX", 60, 17) -:match MyGroup1 /COFFEE/ -:2match MyGroup2 /HUMPPA/ -:3match MyGroup3 /VIM/ -:call clearmatches() -:if getmatches() == [] -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:unlet m1 -:unlet m2 -:unlet m3 -:" --- Check that "setmatches()" restores a list of matches saved by -:" --- "getmatches()" without changes. (Matches with equal priority must also -:" --- remain in the same order.) -:let @r .= "*** Test 8: " -:let m1 = matchadd("MyGroup1", "TODO") -:let m2 = matchadd("MyGroup2", "FIXME", 42) -:let m3 = matchadd("MyGroup3", "XXX", 60, 17) -:match MyGroup1 /COFFEE/ -:2match MyGroup2 /HUMPPA/ -:3match MyGroup3 /VIM/ -:let ml = getmatches() -:call clearmatches() -:call setmatches(ml) -:if getmatches() == ml -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:call clearmatches() -:unlet m1 -:unlet m2 -:unlet m3 -:unlet ml -:" --- Check that "setmatches()" will not add two matches with the same ID. The -:" --- expected behaviour (for now) is to add the first match but not the -:" --- second and to return 0 (even though it is a matter of debate whether -:" --- this can be considered successful behaviour). -:let @r .= "*** Test 9: " -:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}]) -:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0 -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:call clearmatches() -:unlet r1 -:" --- Check that "setmatches()" returns 0 if successful and otherwise -1. -:" --- (A range of valid and invalid input values are tried out to generate the -:" --- return values.) -:let @r .= "*** Test 10: " -:let rs1 = setmatches([]) -:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}]) -:call clearmatches() -:let rf1 = setmatches(0) -:let rf2 = setmatches([0]) -:let rf3 = setmatches([{'wrong key': 'wrong value'}]) -:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1 -: let @r .= "OK\n" -:else -: let @r .= "FAILED\n" -:endif -:unlet rs1 -:unlet rs2 -:unlet rf1 -:unlet rf2 -:unlet rf3 -:" --- Check that "matchaddpos()" positions matches correctly -:let @r .= "*** Test 11:\n" -:set nolazyredraw -:call setline(1, 'abcdefghijklmnopq') -:call matchaddpos("MyGroup1", [[1, 5], [1, 8, 3]], 10, 3) -:1 -:redraw! -:let v1 = screenattr(1, 1) -:let v5 = screenattr(1, 5) -:let v6 = screenattr(1, 6) -:let v8 = screenattr(1, 8) -:let v10 = screenattr(1, 10) -:let v11 = screenattr(1, 11) -:let @r .= string(getmatches())."\n" -:if v1 != v5 && v6 == v1 && v8 == v5 && v10 == v5 && v11 == v1 -: let @r .= "OK\n" -:else -: let @r .= "FAILED: " . v5 . "/" . v6 . "/" . v8 . "/" . v10 . "/" . v11 . "\n" -:endif -:call clearmatches() -:" -:call setline(1, 'abcdΣabcdef') -:call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]]) -:1 -:redraw! -:let v1 = screenattr(1, 1) -:let v4 = screenattr(1, 4) -:let v5 = screenattr(1, 5) -:let v6 = screenattr(1, 6) -:let v7 = screenattr(1, 7) -:let v8 = screenattr(1, 8) -:let v9 = screenattr(1, 9) -:let v10 = screenattr(1, 10) -:let @r .= string(getmatches())."\n" -:if v1 != v4 && v5 == v4 && v6 == v1 && v7 == v1 && v8 == v4 && v9 == v4 && v10 == v1 -: let @r .= "OK\n" -:else -: let @r .= "FAILED: " . v4 . "/" . v5 . "/" . v6 . "/" . v7 . "/" . v8 . "/" . v9 . "/" . v10 . "\n" -:endif -:" Check, that setmatches() can correctly restore the matches from matchaddpos() -:call matchadd('MyGroup1', '\%2lmatchadd') -:let m=getmatches() -:call clearmatches() -:call setmatches(m) -:let @r .= string(getmatches())."\n" -G"rp -:/^Results/,$wq! test.out -ENDTEST - -Results of test63: diff --git a/src/testdir/test63.ok b/src/testdir/test63.ok deleted file mode 100644 index 7016daf6bd..0000000000 --- a/src/testdir/test63.ok +++ /dev/null @@ -1,17 +0,0 @@ -Results of test63: -*** Test 1: OK -*** Test 2: OK -*** Test 3: OK -*** Test 4: OK -*** Test 5: OK -*** Test 6: OK -*** Test 7: OK -*** Test 8: OK -*** Test 9: OK -*** Test 10: OK -*** Test 11: -[{'group': 'MyGroup1', 'id': 3, 'priority': 10, 'pos1': [1, 5, 1], 'pos2': [1, 8, 3]}] -OK -[{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}] -OK -[{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}] diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim index c7d651bd96..0245fadb45 100644 --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -21,7 +21,7 @@ source test_join.vim source test_jumps.vim source test_lambda.vim source test_lispwords.vim -source test_matchstrpos.vim +source test_match.vim source test_menu.vim source test_messages.vim source test_partial.vim diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim new file mode 100644 index 0000000000..57dde19bab --- /dev/null +++ b/src/testdir/test_match.vim @@ -0,0 +1,165 @@ +" Test for :match, :2match, :3match, clearmatches(), getmatches(), matchadd(), +" matchaddpos(), matcharg(), matchdelete(), matchstrpos() and setmatches(). + +function Test_matcharg() + highlight MyGroup1 term=bold ctermbg=red guibg=red + highlight MyGroup2 term=italic ctermbg=green guibg=green + highlight MyGroup3 term=underline ctermbg=blue guibg=blue + + " --- Check that "matcharg()" returns the correct group and pattern if a match + " --- is defined. + match MyGroup1 /TODO/ + 2match MyGroup2 /FIXME/ + 3match MyGroup3 /XXX/ + call assert_equal(['MyGroup1', 'TODO'], matcharg(1)) + call assert_equal(['MyGroup2', 'FIXME'], matcharg(2)) + call assert_equal(['MyGroup3', 'XXX'], matcharg(3)) + + " --- Check that "matcharg()" returns an empty list if the argument is not 1, + " --- 2 or 3 (only 0 and 4 are tested). + call assert_equal([], matcharg(0)) + call assert_equal([], matcharg(4)) + + " --- Check that "matcharg()" returns ['', ''] if a match is not defined. + match + 2match + 3match + call assert_equal(['', ''], matcharg(1)) + call assert_equal(['', ''], matcharg(2)) + call assert_equal(['', ''], matcharg(3)) + + " --- Check that "matchadd()" and "getmatches()" agree on added matches and + " --- that default values apply. + let m1 = matchadd("MyGroup1", "TODO") + let m2 = matchadd("MyGroup2", "FIXME", 42) + let m3 = matchadd("MyGroup3", "XXX", 60, 17) + let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, + \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, + \ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] + call assert_equal(ans, getmatches()) + + " --- Check that "matchdelete()" deletes the matches defined in the previous + " --- test correctly. + call matchdelete(m1) + call matchdelete(m2) + call matchdelete(m3) + call assert_equal([], getmatches()) + + " --- Check that "matchdelete()" returns 0 if successful and otherwise -1. + let m = matchadd("MyGroup1", "TODO") + call assert_equal(0, matchdelete(m)) + call assert_fails('call matchdelete(42)', 'E803:') + + " --- Check that "clearmatches()" clears all matches defined by ":match" and + " --- "matchadd()". + let m1 = matchadd("MyGroup1", "TODO") + let m2 = matchadd("MyGroup2", "FIXME", 42) + let m3 = matchadd("MyGroup3", "XXX", 60, 17) + match MyGroup1 /COFFEE/ + 2match MyGroup2 /HUMPPA/ + 3match MyGroup3 /VIM/ + call clearmatches() + call assert_equal([], getmatches()) + + " --- Check that "setmatches()" restores a list of matches saved by + " --- "getmatches()" without changes. (Matches with equal priority must also + " --- remain in the same order.) + let m1 = matchadd("MyGroup1", "TODO") + let m2 = matchadd("MyGroup2", "FIXME", 42) + let m3 = matchadd("MyGroup3", "XXX", 60, 17) + match MyGroup1 /COFFEE/ + 2match MyGroup2 /HUMPPA/ + 3match MyGroup3 /VIM/ + let ml = getmatches() + call clearmatches() + call setmatches(ml) + call assert_equal(ml, getmatches()) + call clearmatches() + + " --- Check that "setmatches()" will not add two matches with the same ID. The + " --- expected behaviour (for now) is to add the first match but not the + " --- second and to return 0 (even though it is a matter of debate whether + " --- this can be considered successful behaviour). + let data = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, + \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}] + call assert_fails('call setmatches(data)', 'E801:') + call assert_equal([data[0]], getmatches()) + call clearmatches() + + " --- Check that "setmatches()" returns 0 if successful and otherwise -1. + " --- (A range of valid and invalid input values are tried out to generate the + " --- return values.) + call assert_equal(0, setmatches([])) + call assert_equal(0, setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])) + call clearmatches() + call assert_fails('call setmatches(0)', 'E714:') + call assert_fails('call setmatches([0])', 'E474:') + call assert_fails("call setmatches([{'wrong key': 'wrong value'}])", 'E474:') + + call setline(1, 'abcdefghijklmnopq') + call matchaddpos("MyGroup1", [[1, 5], [1, 8, 3]], 10, 3) + 1 + redraw! + let v1 = screenattr(1, 1) + let v5 = screenattr(1, 5) + let v6 = screenattr(1, 6) + let v8 = screenattr(1, 8) + let v10 = screenattr(1, 10) + let v11 = screenattr(1, 11) + call assert_notequal(v1, v5) + call assert_equal(v6, v1) + call assert_equal(v8, v5) + call assert_equal(v10, v5) + call assert_equal(v11, v1) + call assert_equal([{'group': 'MyGroup1', 'id': 3, 'priority': 10, 'pos1': [1, 5, 1], 'pos2': [1, 8, 3]}], getmatches()) + call clearmatches() + + " + if has('multi_byte') + call setline(1, 'abcdΣabcdef') + call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]]) + 1 + redraw! + let v1 = screenattr(1, 1) + let v4 = screenattr(1, 4) + let v5 = screenattr(1, 5) + let v6 = screenattr(1, 6) + let v7 = screenattr(1, 7) + let v8 = screenattr(1, 8) + let v9 = screenattr(1, 9) + let v10 = screenattr(1, 10) + call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches()) + call assert_notequal(v1, v4) + call assert_equal(v5, v4) + call assert_equal(v6, v1) + call assert_equal(v7, v1) + call assert_equal(v8, v4) + call assert_equal(v9, v4) + call assert_equal(v10, v1) + + " Check, that setmatches() can correctly restore the matches from matchaddpos() + call matchadd('MyGroup1', '\%2lmatchadd') + let m=getmatches() + call clearmatches() + call setmatches(m) + call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}], getmatches()) + endif + + highlight MyGroup1 NONE + highlight MyGroup2 NONE + highlight MyGroup3 NONE +endfunc + +func Test_matchstrpos() + call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing')) + + call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2)) + + call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5)) + + call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing')) + + call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img')) +endfunc + +" vim: et ts=2 sw=2 diff --git a/src/testdir/test_matchstrpos.vim b/src/testdir/test_matchstrpos.vim deleted file mode 100644 index e14765b26b..0000000000 --- a/src/testdir/test_matchstrpos.vim +++ /dev/null @@ -1,13 +0,0 @@ -" Test matchstrpos - -func Test_matchstrpos() - call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing')) - - call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2)) - - call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5)) - - call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing')) - - call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img')) -endfunc diff --git a/src/version.c b/src/version.c index bd2b16c7ab..e6488620a7 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2163, /**/ 2162, /**/ From 66459b7c98c67f8a9d39de8f08e8e8f1fca0e359 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 19:01:55 +0200 Subject: [PATCH 03/12] patch 7.4.2164 Problem: It is not possible to use plugins in an "after" directory to tune the behavior of a package. Solution: First load plugins from non-after directories, then packages and finally plugins in after directories. Reset 'loadplugins' before executing --cmd arguments. --- runtime/doc/starting.txt | 11 ++++++-- src/ex_cmds2.c | 18 ++++++++++++- src/main.c | 19 +++++++++++--- src/testdir/Makefile | 4 ++- src/testdir/setup.vim | 3 ++- src/testdir/shared.vim | 21 +++++++++++++++ src/testdir/test_startup.vim | 50 +++++++++++++++++++++++++++++++++++- src/version.c | 2 ++ src/vim.h | 2 ++ 9 files changed, 120 insertions(+), 10 deletions(-) diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index bcd1eadfe7..a4847c2e29 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 7.4. Last change: 2016 Jul 29 +*starting.txt* For Vim version 7.4. Last change: 2016 Aug 06 VIM REFERENCE MANUAL by Bram Moolenaar @@ -858,6 +858,8 @@ accordingly. Vim proceeds in this order: searched for the "plugin" sub-directory and all files ending in ".vim" will be sourced (in alphabetical order per directory), also in subdirectories. + However, directories in 'runtimepath' ending in "after" are skipped + here and only loaded after packages, see below. Loading plugins won't be done when: - The 'loadplugins' option was reset in a vimrc file. - The |--noplugin| command line argument is used. @@ -865,13 +867,18 @@ accordingly. Vim proceeds in this order: - When Vim was compiled without the |+eval| feature. Note that using "-c 'set noloadplugins'" doesn't work, because the commands from the command line have not been executed yet. You can - use "--cmd 'set noloadplugins'" |--cmd|. + use "--cmd 'set noloadplugins'" or "--cmd 'set loadplugins'" |--cmd|. Packages are loaded. These are plugins, as above, but found in the "start" directory of each entry in 'packpath'. Every plugin directory found is added in 'runtimepath' and then the plugins are sourced. See |packages|. + The plugins scripts are loaded, as above, but now only the directories + ending in "after" are used. Note that 'runtimepath' will have changed + if packages have been found, but that should not add a directory + ending in "after". + 5. Set 'shellpipe' and 'shellredir' The 'shellpipe' and 'shellredir' options are set according to the value of the 'shell' option, unless they have been set before. diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 2cebbebca8..0e332dd421 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -3240,15 +3240,30 @@ do_in_path( rtp = rtp_copy; while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) { + size_t buflen; + /* Copy the path from 'runtimepath' to buf[]. */ copy_option_part(&rtp, buf, MAXPATHL, ","); + buflen = STRLEN(buf); + + /* Skip after or non-after directories. */ + if (flags & (DIP_NOAFTER | DIP_AFTER)) + { + int is_after = buflen >= 5 + && STRCMP(buf + buflen - 5, "after") == 0; + + if ((is_after && (flags & DIP_NOAFTER)) + || (!is_after && (flags & DIP_AFTER))) + continue; + } + if (name == NULL) { (*callback)(buf, (void *) &cookie); if (!did_one) did_one = (cookie == NULL); } - else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL) + else if (buflen + STRLEN(name) + 2 < MAXPATHL) { add_pathsep(buf); tail = buf + STRLEN(buf); @@ -3512,6 +3527,7 @@ static int did_source_packages = FALSE; /* * ":packloadall" * Find plugins in the package directories and source them. + * "eap" is NULL when invoked during startup. */ void ex_packloadall(exarg_T *eap) diff --git a/src/main.c b/src/main.c index 51e4483e3e..48e90c27ff 100644 --- a/src/main.c +++ b/src/main.c @@ -439,6 +439,11 @@ vim_main2(int argc UNUSED, char **argv UNUSED) #endif #ifndef NO_VIM_MAIN + /* Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. + * Allows for setting 'loadplugins' there. */ + if (params.use_vimrc != NULL && STRCMP(params.use_vimrc, "NONE") == 0) + p_lpl = FALSE; + /* Execute --cmd arguments. */ exe_pre_commands(¶ms); @@ -453,14 +458,22 @@ vim_main2(int argc UNUSED, char **argv UNUSED) if (p_lpl) { # ifdef VMS /* Somehow VMS doesn't handle the "**". */ - source_runtime((char_u *)"plugin/*.vim", DIP_ALL); + source_runtime((char_u *)"plugin/*.vim", DIP_ALL | DIP_NOAFTER); # else - source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL); + source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); # endif TIME_MSG("loading plugins"); ex_packloadall(NULL); TIME_MSG("loading packages"); + +# ifdef VMS /* Somehow VMS doesn't handle the "**". */ + source_runtime((char_u *)"plugin/*.vim", DIP_ALL | DIP_AFTER); +# else + source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER); +# endif + TIME_MSG("loading after plugins"); + } #endif @@ -2945,8 +2958,6 @@ source_startup_scripts(mparm_T *parmp) if (use_gvimrc == NULL) /* don't load gvimrc either */ use_gvimrc = parmp->use_vimrc; #endif - if (parmp->use_vimrc[2] == 'N') - p_lpl = FALSE; /* don't load plugins either */ } else { diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 5c629ed3f7..2153039d56 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -127,4 +127,6 @@ newtestssilent: $(NEW_TESTS) .vim.res: - $(RUN_VIMTEST) -u NONE -U NONE -S runtest.vim $*.vim + @echo "$(RUN_VIMTEST)" > vimcmd + $(RUN_VIMTEST) -U NONE -S runtest.vim $*.vim + @rm vimcmd diff --git a/src/testdir/setup.vim b/src/testdir/setup.vim index f7e475a81a..dee3de2120 100644 --- a/src/testdir/setup.vim +++ b/src/testdir/setup.vim @@ -1,7 +1,8 @@ " Common preparations for running tests. -" Make sure 'runtimepath' does not include $HOME. +" Make sure 'runtimepath' and 'packpath' does not include $HOME. set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after +let &packpath = &rtp " Only when the +eval feature is present. if 1 diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim index b28a26c0ba..d0be24166a 100644 --- a/src/testdir/shared.vim +++ b/src/testdir/shared.vim @@ -120,3 +120,24 @@ func WaitFor(expr) sleep 10m endfor endfunc + +" Run Vim, using the "vimcmd" file and "-u NORC". +" "before" is a list of commands to be executed before loading plugins. +" "after" is a list of commands to be executed after loading plugins. +" Plugins are not loaded, unless 'loadplugins' is set in "before". +" Return 1 if Vim could be executed. +func RunVim(before, after) + if !filereadable('vimcmd') + return 0 + endif + call writefile(a:before, 'Xbefore.vim') + call writefile(a:after, 'Xafter.vim') + + let cmd = readfile('vimcmd')[0] + let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') + exe "silent !" . cmd . " --cmd 'so Xbefore.vim' -S Xafter.vim" + + call delete('Xbefore.vim') + call delete('Xafter.vim') + return 1 +endfunc diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 0630b2a841..26e7b9f8ee 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -1,8 +1,56 @@ -" Check that loading startup.vim works. +" Tests for startup. +source shared.vim + +" Check that loading startup.vim works. func Test_startup_script() set compatible source $VIMRUNTIME/defaults.vim call assert_equal(0, &compatible) endfunc + +" Verify the order in which plugins are loaded: +" 1. plugins in non-after directories +" 2. packages +" 3. plugins in after directories +func Test_after_comes_later() + let before = [ + \ 'let $HOME = "/does/not/exist"', + \ 'set loadplugins', + \ 'set rtp=Xhere,Xafter', + \ 'set packpath=Xhere,Xafter', + \ 'set nomore', + \ ] + let after = [ + \ 'redir! > Xtestout', + \ 'scriptnames', + \ 'redir END', + \ 'quit', + \ ] + call mkdir('Xhere/plugin', 'p') + call writefile(['let done = 1'], 'Xhere/plugin/here.vim') + call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') + call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') + + call mkdir('Xafter/plugin', 'p') + call writefile(['let done = 1'], 'Xafter/plugin/later.vim') + + call RunVim(before, after) + + let lines = readfile('Xtestout') + let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] + let found = [] + for line in lines + for one in expected + if line =~ one + call add(found, one) + endif + endfor + endfor + call assert_equal(expected, found) + + call delete('Xtestout') + call delete('Xhere', 'rf') + call delete('Xafter', 'rf') +endfunc diff --git a/src/version.c b/src/version.c index e6488620a7..142801db42 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2164, /**/ 2163, /**/ diff --git a/src/vim.h b/src/vim.h index 398fcc548f..928a558fba 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2451,6 +2451,8 @@ int vim_main2(int argc, char **argv); #define DIP_START 0x08 /* also use "start" directory in 'packpath' */ #define DIP_OPT 0x10 /* also use "opt" directory in 'packpath' */ #define DIP_NORTP 0x20 /* do not use 'runtimepath' */ +#define DIP_NOAFTER 0x40 /* skip "after" directories */ +#define DIP_AFTER 0x80 /* only use "after" directories */ /* Lowest number used for window ID. Cannot have this many windows. */ #define LOWEST_WIN_ID 1000 From 83b3c3d8a0fa1afed06c13163b9f72c0925f2a61 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 19:16:43 +0200 Subject: [PATCH 04/12] patch 7.4.2165 Problem: Startup test fails on MS-Windows. Solution: Don't check output if RunVim() returns zero. --- src/testdir/test_startup.vim | 23 ++++++++++++----------- src/version.c | 2 ++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 26e7b9f8ee..da6a3f6f80 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -36,19 +36,20 @@ func Test_after_comes_later() call mkdir('Xafter/plugin', 'p') call writefile(['let done = 1'], 'Xafter/plugin/later.vim') - call RunVim(before, after) + if RunVim(before, after) - let lines = readfile('Xtestout') - let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] - let found = [] - for line in lines - for one in expected - if line =~ one - call add(found, one) - endif + let lines = readfile('Xtestout') + let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] + let found = [] + for line in lines + for one in expected + if line =~ one + call add(found, one) + endif + endfor endfor - endfor - call assert_equal(expected, found) + call assert_equal(expected, found) + endif call delete('Xtestout') call delete('Xhere', 'rf') diff --git a/src/version.c b/src/version.c index 142801db42..e3ecd93c76 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2165, /**/ 2164, /**/ From 328604307ba26e3182eb0b096e820f9cd346c2dd Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 19:24:23 +0200 Subject: [PATCH 05/12] patch 7.4.2166 Problem: Small build can't run startup test. Solution: Skip the test. --- src/testdir/test_startup.vim | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index da6a3f6f80..047bc34a2f 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -15,6 +15,9 @@ endfunc " 2. packages " 3. plugins in after directories func Test_after_comes_later() + if !has('packages') + return + endif let before = [ \ 'let $HOME = "/does/not/exist"', \ 'set loadplugins', diff --git a/src/version.c b/src/version.c index e3ecd93c76..2add5968f2 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2166, /**/ 2165, /**/ From c96a2f3b887d9a1f850f0dacc92616bee11f966b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 19:45:31 +0200 Subject: [PATCH 06/12] patch 7.4.2167 Problem: Small build can't run tests. Solution: Don't try setting 'packpath'. --- src/testdir/setup.vim | 4 +++- src/version.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testdir/setup.vim b/src/testdir/setup.vim index dee3de2120..a02840158b 100644 --- a/src/testdir/setup.vim +++ b/src/testdir/setup.vim @@ -2,7 +2,9 @@ " Make sure 'runtimepath' and 'packpath' does not include $HOME. set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after -let &packpath = &rtp +if has('packages') + let &packpath = &rtp +endif " Only when the +eval feature is present. if 1 diff --git a/src/version.c b/src/version.c index 2add5968f2..d5623c4cd7 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2167, /**/ 2166, /**/ From 5b4a3767f6d1760ba1ce103ef3cffb696ece0244 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 20:36:34 +0200 Subject: [PATCH 07/12] patch 7.4.2168 Problem: Not running the startup test on MS-Windows. Solution: Write vimcmd. --- src/testdir/Make_dos.mak | 2 ++ src/testdir/Make_ming.mak | 12 +++++++----- src/version.c | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index 66cf12f2e1..b6aaa6e68f 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -114,4 +114,6 @@ bench_re_freeze.out: bench_re_freeze.vim newtests: $(NEW_TESTS) .vim.res: + @echo "$(VIMPROG)" > vimcmd $(VIMPROG) -u NONE $(NO_PLUGIN) -S runtest.vim $*.vim + @del vimcmd diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak index c2c0239524..33306910ad 100644 --- a/src/testdir/Make_ming.mak +++ b/src/testdir/Make_ming.mak @@ -48,21 +48,21 @@ $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS_WIN32) $(NEW_TESTS): $(SCRIPTS_FIRST) .SUFFIXES: .in .out .res .vim vimall: fixff $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS_WIN32) newtests - echo ALL DONE + @echo ALL DONE nongui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests - echo ALL DONE + @echo ALL DONE benchmark: $(SCRIPTS_BENCH) small: nolog - echo ALL DONE + @echo ALL DONE gui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests - echo ALL DONE + @echo ALL DONE win32: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests - echo ALL DONE + @echo ALL DONE # TODO: find a way to avoid changing the distributed files. fixff: @@ -117,5 +117,7 @@ bench_re_freeze.out: bench_re_freeze.vim newtests: $(NEW_TESTS) .vim.res: + @echo "$(VIMPROG)" > vimcmd $(VIMPROG) -u NONE $(NO_PLUGIN) -S runtest.vim $*.vim + @$(DEL) vimcmd diff --git a/src/version.c b/src/version.c index d5623c4cd7..1b55e4fba5 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2168, /**/ 2167, /**/ From 446cce6d537b036467033975a86729dbdc83f860 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 21:37:27 +0200 Subject: [PATCH 08/12] patch 7.4.2169 Problem: Startup test gets stuck on MS-Windows. Solution: Use double quotes. --- src/testdir/shared.vim | 5 ++++- src/testdir/test_startup.vim | 2 ++ src/version.c | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim index d0be24166a..056ecd926b 100644 --- a/src/testdir/shared.vim +++ b/src/testdir/shared.vim @@ -135,7 +135,10 @@ func RunVim(before, after) let cmd = readfile('vimcmd')[0] let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') - exe "silent !" . cmd . " --cmd 'so Xbefore.vim' -S Xafter.vim" + if cmd !~ '-u NONE' + let cmd = cmd . ' -u NONE' + endif + exe "silent !" . cmd . " --cmd \"so Xbefore.vim\" -S Xafter.vim" call delete('Xbefore.vim') call delete('Xafter.vim') diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 047bc34a2f..14e78ce3c4 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -19,6 +19,8 @@ func Test_after_comes_later() return endif let before = [ + \ 'set nocp viminfo+=nviminfo', + \ 'set guioptions+=M', \ 'let $HOME = "/does/not/exist"', \ 'set loadplugins', \ 'set rtp=Xhere,Xafter', diff --git a/src/version.c b/src/version.c index 1b55e4fba5..e57e0fc931 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2169, /**/ 2168, /**/ From 8e97bd74b5377753597e3d98e7123d8985c7fffd Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 22:05:07 +0200 Subject: [PATCH 09/12] patch 7.4.2170 Problem: Cannot get information about timers. Solution: Add timer_info(). --- runtime/doc/eval.txt | 36 +++++++++++++++++++----- src/evalfunc.c | 27 ++++++++++++++++++ src/ex_cmds2.c | 62 ++++++++++++++++++++++++++++++++++++++++-- src/proto/ex_cmds2.pro | 2 ++ src/version.c | 2 ++ 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 04edbd3674..d6269d5a3d 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2016 Aug 02 +*eval.txt* For Vim version 7.4. Last change: 2016 Aug 06 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2339,6 +2339,7 @@ test_null_list() List null value for testing test_null_partial() Funcref null value for testing test_null_string() String null value for testing test_settime({expr}) none set current time for testing +timer_info([{id}]) List information about timers timer_start({time}, {callback} [, {options}]) Number create a timer timer_stop({timer}) none stop a timer @@ -3392,9 +3393,13 @@ exepath({expr}) *exepath()* an empty string is returned. *exists()* -exists({expr}) The result is a Number, which is |TRUE| if {expr} is - defined, zero otherwise. The {expr} argument is a string, - which contains one of these: +exists({expr}) The result is a Number, which is |TRUE| if {expr} is defined, + zero otherwise. + + For checking for a supported feature use |has()|. + For checking if a file exists use |filereadable()|. + + The {expr} argument is a string, which contains one of these: &option-name Vim option (only checks if it exists, not if it really works) +option-name Vim option that works. @@ -3442,7 +3447,6 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is event and pattern. ##event autocommand for this event is supported. - For checking for a supported feature use |has()|. Examples: > exists("&shortname") @@ -5476,7 +5480,8 @@ matchadd({group}, {pattern}[, {priority}[, {id}[, {dict}]]]) available from |getmatches()|. All matches can be deleted in one operation by |clearmatches()|. -matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]]) *matchaddpos()* + *matchaddpos()* +matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]]) Same as |matchadd()|, but requires a list of positions {pos} instead of a pattern. This command is faster than |matchadd()| because it does not require to handle regular expressions and @@ -7536,6 +7541,23 @@ test_settime({expr}) *test_settime()* {expr} must evaluate to a number. When the value is zero the normal behavior is restored. + *timer_info()* +timer_info([{id}]) + Return a list with information about timers. + When {id} is given only information about this timer is + returned. When timer {id} does not exist an empty list is + returned. + When {id} is omitted information about all timers is returned. + + For each timer the information is stored in a Dictionary with + these items: + "id" the timer ID + "time" time the timer was started with + "remaining" time until the timer fires + "repeat" number of times the timer will still fire; + -1 means forever + "callback" the callback + *timer_start()* timer_start({time}, {callback} [, {options}]) Create a timer and return the timer ID. @@ -7566,7 +7588,7 @@ timer_start({time}, {callback} [, {options}]) timer_stop({timer}) *timer_stop()* Stop a timer. The timer callback will no longer be invoked. {timer} is an ID returned by timer_start(), thus it must be a - Number. + Number. If {timer} does not exist there is no error. tolower({expr}) *tolower()* The result is a copy of the String given, with all uppercase diff --git a/src/evalfunc.c b/src/evalfunc.c index 3754534460..50fa3bf720 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -396,6 +396,7 @@ static void f_tan(typval_T *argvars, typval_T *rettv); static void f_tanh(typval_T *argvars, typval_T *rettv); #endif #ifdef FEAT_TIMERS +static void f_timer_info(typval_T *argvars, typval_T *rettv); static void f_timer_start(typval_T *argvars, typval_T *rettv); static void f_timer_stop(typval_T *argvars, typval_T *rettv); #endif @@ -815,6 +816,7 @@ static struct fst {"test_null_string", 0, 0, f_test_null_string}, {"test_settime", 1, 1, f_test_settime}, #ifdef FEAT_TIMERS + {"timer_info", 0, 1, f_timer_info}, {"timer_start", 2, 3, f_timer_start}, {"timer_stop", 1, 1, f_timer_stop}, #endif @@ -11960,6 +11962,31 @@ free_callback(char_u *callback, partial_T *partial) #endif #ifdef FEAT_TIMERS +/* + * "timer_info([timer])" function + */ + static void +f_timer_info(typval_T *argvars, typval_T *rettv) +{ + timer_T *timer = NULL; + + if (rettv_list_alloc(rettv) != OK) + return; + if (argvars[0].v_type != VAR_UNKNOWN) + { + if (argvars[0].v_type != VAR_NUMBER) + EMSG(_(e_number_exp)); + else + { + timer = find_timer((int)get_tv_number(&argvars[0])); + if (timer != NULL) + add_timer_info(rettv, timer); + } + } + else + add_timer_info_all(rettv); +} + /* * "timer_start(time, callback [, options])" function */ diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 0e332dd421..f6c054b8d2 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1139,10 +1139,8 @@ create_timer(long msec, int repeat) timer->tr_id = ++last_timer_id; insert_timer(timer); if (repeat != 0) - { timer->tr_repeat = repeat - 1; - timer->tr_interval = msec; - } + timer->tr_interval = msec; profile_setlimit(msec, &timer->tr_due); return timer; @@ -1253,6 +1251,64 @@ stop_timer(timer_T *timer) free_timer(timer); } + void +add_timer_info(typval_T *rettv, timer_T *timer) +{ + list_T *list = rettv->vval.v_list; + dict_T *dict = dict_alloc(); + dictitem_T *di; + long remaining; + proftime_T now; + + if (dict == NULL) + return; + list_append_dict(list, dict); + + dict_add_nr_str(dict, "id", (long)timer->tr_id, NULL); + dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL); + + profile_start(&now); +# ifdef WIN3264 + remaining = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart) + / (double)fr.QuadPart) * 1000); +# else + remaining = (timer->tr_due.tv_sec - now.tv_sec) * 1000 + + (timer->tr_due.tv_usec - now.tv_usec) / 1000; +# endif + dict_add_nr_str(dict, "remaining", (long)remaining, NULL); + + dict_add_nr_str(dict, "repeat", + (long)(timer->tr_repeat < 0 ? -1 : timer->tr_repeat + 1), NULL); + + di = dictitem_alloc((char_u *)"callback"); + if (di != NULL) + { + if (dict_add(dict, di) == FAIL) + vim_free(di); + else if (timer->tr_partial != NULL) + { + di->di_tv.v_type = VAR_PARTIAL; + di->di_tv.vval.v_partial = timer->tr_partial; + ++timer->tr_partial->pt_refcount; + } + else + { + di->di_tv.v_type = VAR_FUNC; + di->di_tv.vval.v_string = vim_strsave(timer->tr_callback); + } + di->di_tv.v_lock = 0; + } +} + + void +add_timer_info_all(typval_T *rettv) +{ + timer_T *timer; + + for (timer = first_timer; timer != NULL; timer = timer->tr_next) + add_timer_info(rettv, timer); +} + /* * Mark references in partials of timers. */ diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro index c7a860b9f0..977f5c0de1 100644 --- a/src/proto/ex_cmds2.pro +++ b/src/proto/ex_cmds2.pro @@ -22,6 +22,8 @@ timer_T *create_timer(long msec, int repeat); long check_due_timer(void); timer_T *find_timer(int id); void stop_timer(timer_T *timer); +void add_timer_info(typval_T *rettv, timer_T *timer); +void add_timer_info_all(typval_T *rettv); int set_ref_in_timer(int copyID); void timer_free_all(void); void profile_divide(proftime_T *tm, int count, proftime_T *tm2); diff --git a/src/version.c b/src/version.c index e57e0fc931..b1be507afd 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2170, /**/ 2169, /**/ From 00ff380295338eedb6138ce87590cc6bed102e9d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 22:27:28 +0200 Subject: [PATCH 10/12] patch 7.4.2171 Problem: MS-Windows build fails. Solution: Add QueryPerformanceCounter(). --- src/ex_cmds2.c | 4 ++++ src/version.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index f6c054b8d2..6cf26e9931 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1259,6 +1259,9 @@ add_timer_info(typval_T *rettv, timer_T *timer) dictitem_T *di; long remaining; proftime_T now; +# ifdef WIN3264 + LARGE_INTEGER fr; +#endif if (dict == NULL) return; @@ -1269,6 +1272,7 @@ add_timer_info(typval_T *rettv, timer_T *timer) profile_start(&now); # ifdef WIN3264 + QueryPerformanceFrequency(&fr); remaining = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart) / (double)fr.QuadPart) * 1000); # else diff --git a/src/version.c b/src/version.c index b1be507afd..98dd5f4b2d 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2171, /**/ 2170, /**/ From 472a0a880a709c027f4b19cfa56c08e78818112d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 22:31:42 +0200 Subject: [PATCH 11/12] patch 7.4.2172 Problem: No test for "vim --help". Solution: Add a test. --- src/testdir/shared.vim | 23 +++++++++++++++++------ src/testdir/test_startup.vim | 23 ++++++++++++++++++++++- src/version.c | 2 ++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim index 056ecd926b..5985ff9e1c 100644 --- a/src/testdir/shared.vim +++ b/src/testdir/shared.vim @@ -126,21 +126,32 @@ endfunc " "after" is a list of commands to be executed after loading plugins. " Plugins are not loaded, unless 'loadplugins' is set in "before". " Return 1 if Vim could be executed. -func RunVim(before, after) +func RunVim(before, after, arguments) if !filereadable('vimcmd') return 0 endif - call writefile(a:before, 'Xbefore.vim') - call writefile(a:after, 'Xafter.vim') + let args = a:arguments + if len(a:before) > 0 + call writefile(a:before, 'Xbefore.vim') + let args .= ' --cmd "so Xbefore.vim"' + endif + if len(a:after) > 0 + call writefile(a:after, 'Xafter.vim') + let args .= ' -S Xafter.vim' + endif let cmd = readfile('vimcmd')[0] let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') if cmd !~ '-u NONE' let cmd = cmd . ' -u NONE' endif - exe "silent !" . cmd . " --cmd \"so Xbefore.vim\" -S Xafter.vim" + exe "silent !" . cmd . ' ' . args - call delete('Xbefore.vim') - call delete('Xafter.vim') + if len(a:before) > 0 + call delete('Xbefore.vim') + endif + if len(a:after) > 0 + call delete('Xafter.vim') + endif return 1 endfunc diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 14e78ce3c4..d2463f476d 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -41,7 +41,7 @@ func Test_after_comes_later() call mkdir('Xafter/plugin', 'p') call writefile(['let done = 1'], 'Xafter/plugin/later.vim') - if RunVim(before, after) + if RunVim(before, after, '') let lines = readfile('Xtestout') let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] @@ -60,3 +60,24 @@ func Test_after_comes_later() call delete('Xhere', 'rf') call delete('Xafter', 'rf') endfunc + +func Test_help_arg() + if RunVim([], [], '--help >Xtestout') + let lines = readfile('Xtestout') + call assert_true(len(lines) > 20) + call assert_true(lines[0] =~ 'Vi IMproved') + + " check if couple of lines are there + let found = 0 + for line in lines + if line =~ '-R.*Readonly mode' + let found += 1 + endif + if line =~ '--version' + let found += 1 + endif + endfor + call assert_equal(2, found) + endif + call delete('Xtestout') +endfunc diff --git a/src/version.c b/src/version.c index 98dd5f4b2d..a7af2939fa 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2172, /**/ 2171, /**/ From 3321e9d8a36c91c62d8ba3d43430b5c213b87f8b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 6 Aug 2016 23:03:59 +0200 Subject: [PATCH 12/12] patch 7.4.2173 Problem: Can't test help on MS-Windows. Solution: Skip the test. --- src/testdir/test_startup.vim | 4 ++++ src/version.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index d2463f476d..f21f4c35be 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -62,6 +62,10 @@ func Test_after_comes_later() endfunc func Test_help_arg() + if !has('unix') && has('gui') + " this doesn't work with gvim on MS-Windows + return + endif if RunVim([], [], '--help >Xtestout') let lines = readfile('Xtestout') call assert_true(len(lines) > 20) diff --git a/src/version.c b/src/version.c index a7af2939fa..9cf031bdff 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2173, /**/ 2172, /**/