Skip to content

Commit 66459b7

Browse files
committed
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.
1 parent d76a0c1 commit 66459b7

9 files changed

Lines changed: 120 additions & 10 deletions

File tree

runtime/doc/starting.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*starting.txt* For Vim version 7.4. Last change: 2016 Jul 29
1+
*starting.txt* For Vim version 7.4. Last change: 2016 Aug 06
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -858,20 +858,27 @@ accordingly. Vim proceeds in this order:
858858
searched for the "plugin" sub-directory and all files ending in ".vim"
859859
will be sourced (in alphabetical order per directory), also in
860860
subdirectories.
861+
However, directories in 'runtimepath' ending in "after" are skipped
862+
here and only loaded after packages, see below.
861863
Loading plugins won't be done when:
862864
- The 'loadplugins' option was reset in a vimrc file.
863865
- The |--noplugin| command line argument is used.
864866
- The "-u NONE" command line argument is used |-u|.
865867
- When Vim was compiled without the |+eval| feature.
866868
Note that using "-c 'set noloadplugins'" doesn't work, because the
867869
commands from the command line have not been executed yet. You can
868-
use "--cmd 'set noloadplugins'" |--cmd|.
870+
use "--cmd 'set noloadplugins'" or "--cmd 'set loadplugins'" |--cmd|.
869871

870872
Packages are loaded. These are plugins, as above, but found in the
871873
"start" directory of each entry in 'packpath'. Every plugin directory
872874
found is added in 'runtimepath' and then the plugins are sourced. See
873875
|packages|.
874876

877+
The plugins scripts are loaded, as above, but now only the directories
878+
ending in "after" are used. Note that 'runtimepath' will have changed
879+
if packages have been found, but that should not add a directory
880+
ending in "after".
881+
875882
5. Set 'shellpipe' and 'shellredir'
876883
The 'shellpipe' and 'shellredir' options are set according to the
877884
value of the 'shell' option, unless they have been set before.

src/ex_cmds2.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3240,15 +3240,30 @@ do_in_path(
32403240
rtp = rtp_copy;
32413241
while (*rtp != NUL && ((flags & DIP_ALL) || !did_one))
32423242
{
3243+
size_t buflen;
3244+
32433245
/* Copy the path from 'runtimepath' to buf[]. */
32443246
copy_option_part(&rtp, buf, MAXPATHL, ",");
3247+
buflen = STRLEN(buf);
3248+
3249+
/* Skip after or non-after directories. */
3250+
if (flags & (DIP_NOAFTER | DIP_AFTER))
3251+
{
3252+
int is_after = buflen >= 5
3253+
&& STRCMP(buf + buflen - 5, "after") == 0;
3254+
3255+
if ((is_after && (flags & DIP_NOAFTER))
3256+
|| (!is_after && (flags & DIP_AFTER)))
3257+
continue;
3258+
}
3259+
32453260
if (name == NULL)
32463261
{
32473262
(*callback)(buf, (void *) &cookie);
32483263
if (!did_one)
32493264
did_one = (cookie == NULL);
32503265
}
3251-
else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
3266+
else if (buflen + STRLEN(name) + 2 < MAXPATHL)
32523267
{
32533268
add_pathsep(buf);
32543269
tail = buf + STRLEN(buf);
@@ -3512,6 +3527,7 @@ static int did_source_packages = FALSE;
35123527
/*
35133528
* ":packloadall"
35143529
* Find plugins in the package directories and source them.
3530+
* "eap" is NULL when invoked during startup.
35153531
*/
35163532
void
35173533
ex_packloadall(exarg_T *eap)

src/main.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,11 @@ vim_main2(int argc UNUSED, char **argv UNUSED)
439439
#endif
440440

441441
#ifndef NO_VIM_MAIN
442+
/* Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
443+
* Allows for setting 'loadplugins' there. */
444+
if (params.use_vimrc != NULL && STRCMP(params.use_vimrc, "NONE") == 0)
445+
p_lpl = FALSE;
446+
442447
/* Execute --cmd arguments. */
443448
exe_pre_commands(&params);
444449

@@ -453,14 +458,22 @@ vim_main2(int argc UNUSED, char **argv UNUSED)
453458
if (p_lpl)
454459
{
455460
# ifdef VMS /* Somehow VMS doesn't handle the "**". */
456-
source_runtime((char_u *)"plugin/*.vim", DIP_ALL);
461+
source_runtime((char_u *)"plugin/*.vim", DIP_ALL | DIP_NOAFTER);
457462
# else
458-
source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL);
463+
source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER);
459464
# endif
460465
TIME_MSG("loading plugins");
461466

462467
ex_packloadall(NULL);
463468
TIME_MSG("loading packages");
469+
470+
# ifdef VMS /* Somehow VMS doesn't handle the "**". */
471+
source_runtime((char_u *)"plugin/*.vim", DIP_ALL | DIP_AFTER);
472+
# else
473+
source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER);
474+
# endif
475+
TIME_MSG("loading after plugins");
476+
464477
}
465478
#endif
466479

@@ -2945,8 +2958,6 @@ source_startup_scripts(mparm_T *parmp)
29452958
if (use_gvimrc == NULL) /* don't load gvimrc either */
29462959
use_gvimrc = parmp->use_vimrc;
29472960
#endif
2948-
if (parmp->use_vimrc[2] == 'N')
2949-
p_lpl = FALSE; /* don't load plugins either */
29502961
}
29512962
else
29522963
{

src/testdir/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,6 @@ newtestssilent: $(NEW_TESTS)
127127

128128

129129
.vim.res:
130-
$(RUN_VIMTEST) -u NONE -U NONE -S runtest.vim $*.vim
130+
@echo "$(RUN_VIMTEST)" > vimcmd
131+
$(RUN_VIMTEST) -U NONE -S runtest.vim $*.vim
132+
@rm vimcmd

src/testdir/setup.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
" Common preparations for running tests.
22

3-
" Make sure 'runtimepath' does not include $HOME.
3+
" Make sure 'runtimepath' and 'packpath' does not include $HOME.
44
set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
5+
let &packpath = &rtp
56

67
" Only when the +eval feature is present.
78
if 1

src/testdir/shared.vim

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,24 @@ func WaitFor(expr)
120120
sleep 10m
121121
endfor
122122
endfunc
123+
124+
" Run Vim, using the "vimcmd" file and "-u NORC".
125+
" "before" is a list of commands to be executed before loading plugins.
126+
" "after" is a list of commands to be executed after loading plugins.
127+
" Plugins are not loaded, unless 'loadplugins' is set in "before".
128+
" Return 1 if Vim could be executed.
129+
func RunVim(before, after)
130+
if !filereadable('vimcmd')
131+
return 0
132+
endif
133+
call writefile(a:before, 'Xbefore.vim')
134+
call writefile(a:after, 'Xafter.vim')
135+
136+
let cmd = readfile('vimcmd')[0]
137+
let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
138+
exe "silent !" . cmd . " --cmd 'so Xbefore.vim' -S Xafter.vim"
139+
140+
call delete('Xbefore.vim')
141+
call delete('Xafter.vim')
142+
return 1
143+
endfunc

src/testdir/test_startup.vim

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,56 @@
1-
" Check that loading startup.vim works.
1+
" Tests for startup.
2+
3+
source shared.vim
24

5+
" Check that loading startup.vim works.
36
func Test_startup_script()
47
set compatible
58
source $VIMRUNTIME/defaults.vim
69

710
call assert_equal(0, &compatible)
811
endfunc
12+
13+
" Verify the order in which plugins are loaded:
14+
" 1. plugins in non-after directories
15+
" 2. packages
16+
" 3. plugins in after directories
17+
func Test_after_comes_later()
18+
let before = [
19+
\ 'let $HOME = "/does/not/exist"',
20+
\ 'set loadplugins',
21+
\ 'set rtp=Xhere,Xafter',
22+
\ 'set packpath=Xhere,Xafter',
23+
\ 'set nomore',
24+
\ ]
25+
let after = [
26+
\ 'redir! > Xtestout',
27+
\ 'scriptnames',
28+
\ 'redir END',
29+
\ 'quit',
30+
\ ]
31+
call mkdir('Xhere/plugin', 'p')
32+
call writefile(['let done = 1'], 'Xhere/plugin/here.vim')
33+
call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
34+
call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
35+
36+
call mkdir('Xafter/plugin', 'p')
37+
call writefile(['let done = 1'], 'Xafter/plugin/later.vim')
38+
39+
call RunVim(before, after)
40+
41+
let lines = readfile('Xtestout')
42+
let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
43+
let found = []
44+
for line in lines
45+
for one in expected
46+
if line =~ one
47+
call add(found, one)
48+
endif
49+
endfor
50+
endfor
51+
call assert_equal(expected, found)
52+
53+
call delete('Xtestout')
54+
call delete('Xhere', 'rf')
55+
call delete('Xafter', 'rf')
56+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2164,
766768
/**/
767769
2163,
768770
/**/

src/vim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,8 @@ int vim_main2(int argc, char **argv);
24512451
#define DIP_START 0x08 /* also use "start" directory in 'packpath' */
24522452
#define DIP_OPT 0x10 /* also use "opt" directory in 'packpath' */
24532453
#define DIP_NORTP 0x20 /* do not use 'runtimepath' */
2454+
#define DIP_NOAFTER 0x40 /* skip "after" directories */
2455+
#define DIP_AFTER 0x80 /* only use "after" directories */
24542456

24552457
/* Lowest number used for window ID. Cannot have this many windows. */
24562458
#define LOWEST_WIN_ID 1000

0 commit comments

Comments
 (0)