patch 7.4.1486

Problem:    ":loadplugin" is not optimal, some people find it confusing.
Solution:   Only use ":packadd" with an optional "!".
This commit is contained in:
Bram Moolenaar
2016-03-04 22:12:23 +01:00
parent 014069a7ac
commit f365482736
6 changed files with 109 additions and 105 deletions

View File

@ -433,6 +433,12 @@ You would now have these files under ~/.vim:
pack/my/ever/always/syntax/always.vim pack/my/ever/always/syntax/always.vim
pack/my/opt/mydebug/plugin/debugger.vim pack/my/opt/mydebug/plugin/debugger.vim
If you don't have a package but a single plugin, you need to create the extra
directory level:
% mkdir -p ~/.vim/pack/my/ever/always
% cd ~/.vim/pack/my/ever/always
% unzip /tmp/myplugin.zip
When Vim starts up it scans all directories in 'packpath' for plugins under the When Vim starts up it scans all directories in 'packpath' for plugins under the
"ever" directory and loads them. When found that directory is added to "ever" directory and loads them. When found that directory is added to
'runtimepath'. 'runtimepath'.
@ -443,11 +449,11 @@ In the example Vim will find "my/ever/always/plugin/always.vim" and adds
If the "always" plugin kicks in and sets the 'filetype' to "always", Vim will If the "always" plugin kicks in and sets the 'filetype' to "always", Vim will
find the syntax/always.vim file, because its directory is in 'runtimepath'. find the syntax/always.vim file, because its directory is in 'runtimepath'.
Vim will also load ftdetect files, like with |:loadplugin|. Vim will also load ftdetect files, like with |:packadd|.
*load-plugin* *pack-add*
To load an optional plugin from a pack use the `:loadplugin` command: > To load an optional plugin from a pack use the `:packadd` command: >
:loadplugin mydebug :packadd mydebug
This could be done inside always.vim, if some conditions are met. This could be done inside always.vim, if some conditions are met.
Or you could add this command to your |.vimrc|. Or you could add this command to your |.vimrc|.

View File

@ -810,9 +810,6 @@ EX(CMD_loadview, "loadview", ex_loadview,
EX(CMD_loadkeymap, "loadkeymap", ex_loadkeymap, EX(CMD_loadkeymap, "loadkeymap", ex_loadkeymap,
CMDWIN, CMDWIN,
ADDR_LINES), ADDR_LINES),
EX(CMD_loadplugin, "loadplugin", ex_loadplugin,
BANG|FILE1|TRLBAR|SBOXOK|CMDWIN,
ADDR_LINES),
EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier, EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier,
NEEDARG|EXTRA|NOTRLCOM, NEEDARG|EXTRA|NOTRLCOM,
ADDR_LINES), ADDR_LINES),

View File

@ -3057,88 +3057,75 @@ do_in_runtimepath(
return do_in_path(p_rtp, name, all ? DIP_ALL : 0, callback, cookie); return do_in_path(p_rtp, name, all ? DIP_ALL : 0, callback, cookie);
} }
#ifdef FEAT_AUTOCMD
/* /*
* Source filetype detection scripts, if filetype.vim was already done. * Expand wildcards in "pat" and invoke do_source() for each match.
*/ */
static void static void
may_do_filetypes(char_u *pat) source_all_matches(char_u *pat)
{ {
char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); int num_files;
char_u **files;
int i;
/* If runtime/filetype.vim wasn't loaded yet, the scripts will be found if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK)
* when it loads. */
if (cmd != NULL && eval_to_number(cmd) > 0)
{ {
do_cmdline_cmd((char_u *)"augroup filetypedetect"); for (i = 0; i < num_files; ++i)
do_in_path(p_pp, pat, DIP_ALL, source_callback, NULL); (void)do_source(files[i], FALSE, DOSO_NONE);
do_cmdline_cmd((char_u *)"augroup END"); FreeWild(num_files, files);
} }
vim_free(cmd);
} }
#endif
static void static void
add_pack_plugin(char_u *fname, void *cookie) add_pack_plugin(char_u *fname, void *cookie)
{ {
char_u *p6, *p5, *p4, *p3, *p2, *p1, *p; char_u *p4, *p3, *p2, *p1, *p;
char_u *insp;
int c; int c;
char_u *new_rtp; char_u *new_rtp;
int keep; int keep;
int oldlen; int oldlen;
int addlen; int addlen;
char_u *ffname = fix_fname(fname); char_u *ffname = fix_fname(fname);
int load_file = cookie != NULL; int load_files = cookie != NULL;
if (ffname == NULL) if (ffname == NULL)
return; return;
p6 = p5 = p4 = p3 = p2 = p1 = get_past_head(ffname);
for (p = p1; *p; mb_ptr_adv(p))
if (vim_ispathsep_nocolon(*p))
{
p6 = p5; p5 = p4; p4 = p3; p3 = p2; p2 = p1; p1 = p;
}
/* now we have, load_file == TRUE:
* rtp/pack/name/ever/name/plugin/name.vim
* p6 p5 p4 p3 p2 p1
*
* with load_file == FALSE:
* rtp/pack/name/ever/name
* p4 p3 p2 p1
*/
if (load_file)
p4 = p6;
/* find the part up to "pack" in 'runtimepath' */
c = *p4;
*p4 = NUL;
p = (char_u *)strstr((char *)p_rtp, (char *)ffname);
if (p == NULL)
/* not found, append at the end */
p = p_rtp + STRLEN(p_rtp);
else
/* append after the matching directory. */
p += STRLEN(ffname);
*p4 = c;
if (load_file)
{
c = *p2;
*p2 = NUL;
}
if (strstr((char *)p_rtp, (char *)ffname) == NULL) if (strstr((char *)p_rtp, (char *)ffname) == NULL)
{ {
/* directory not in 'runtimepath', add it */ /* directory not in 'runtimepath', add it */
p4 = p3 = p2 = p1 = get_past_head(ffname);
for (p = p1; *p; mb_ptr_adv(p))
if (vim_ispathsep_nocolon(*p))
{
p4 = p3; p3 = p2; p2 = p1; p1 = p;
}
/* now we have:
* rtp/pack/name/ever/name
* p4 p3 p2 p1
*
* find the part up to "pack" in 'runtimepath' */
c = *p4;
*p4 = NUL;
insp = (char_u *)strstr((char *)p_rtp, (char *)ffname);
if (insp == NULL)
/* not found, append at the end */
insp = p_rtp + STRLEN(p_rtp);
else
{
/* append after the matching directory. */
insp += STRLEN(ffname);
while (*insp != NUL && *insp != ',')
++insp;
}
*p4 = c;
oldlen = (int)STRLEN(p_rtp); oldlen = (int)STRLEN(p_rtp);
addlen = (int)STRLEN(ffname); addlen = (int)STRLEN(ffname);
new_rtp = alloc(oldlen + addlen + 2); new_rtp = alloc(oldlen + addlen + 2);
if (new_rtp == NULL) if (new_rtp == NULL)
{ goto theend;
*p2 = c; keep = (int)(insp - p_rtp);
return;
}
keep = (int)(p - p_rtp);
mch_memmove(new_rtp, p_rtp, keep); mch_memmove(new_rtp, p_rtp, keep);
new_rtp[keep] = ','; new_rtp[keep] = ',';
mch_memmove(new_rtp + keep + 1, ffname, addlen + 1); mch_memmove(new_rtp + keep + 1, ffname, addlen + 1);
@ -3148,53 +3135,55 @@ add_pack_plugin(char_u *fname, void *cookie)
set_option_value((char_u *)"rtp", 0L, new_rtp, 0); set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
vim_free(new_rtp); vim_free(new_rtp);
} }
vim_free(ffname);
if (load_file) if (load_files)
(void)do_source(fname, FALSE, DOSO_NONE); {
static char *plugpat = "%s/plugin/*.vim";
static char *ftpat = "%s/ftdetect/*.vim";
int len;
char_u *pat;
len = (int)STRLEN(ffname) + (int)STRLEN(ftpat);
pat = alloc(len);
if (pat == NULL)
goto theend;
vim_snprintf((char *)pat, len, plugpat, ffname);
source_all_matches(pat);
#ifdef FEAT_AUTOCMD
{
char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
/* If runtime/filetype.vim wasn't loaded yet, the scripts will be
* found when it loads. */
if (cmd != NULL && eval_to_number(cmd) > 0)
{
do_cmdline_cmd((char_u *)"augroup filetypedetect");
vim_snprintf((char *)pat, len, ftpat, ffname);
source_all_matches(pat);
do_cmdline_cmd((char_u *)"augroup END");
}
vim_free(cmd);
}
#endif
}
theend:
vim_free(ffname);
} }
/* /*
* Source the plugins in the package directories. * Find plugins in the package directories and source them.
*/ */
void void
source_packages() source_packages()
{ {
do_in_path(p_pp, (char_u *)"pack/*/ever/*/plugin/*.vim", do_in_path(p_pp, (char_u *)"pack/*/ever/*",
DIP_ALL, add_pack_plugin, p_pp); DIP_ALL + DIP_DIR, add_pack_plugin, p_pp);
#ifdef FEAT_AUTOCMD
may_do_filetypes((char_u *)"pack/*/ever/*/ftdetect/*.vim");
#endif
} }
/* /*
* ":loadplugin {name}" * ":packadd[!] {name}"
*/
void
ex_loadplugin(exarg_T *eap)
{
static char *plugpat = "pack/*/opt/%s/plugin/*.vim";
static char *ftpat = "pack/*/opt/%s/ftdetect/*.vim";
int len;
char *pat;
len = (int)STRLEN(ftpat) + (int)STRLEN(eap->arg);
pat = (char *)alloc(len);
if (pat == NULL)
return;
vim_snprintf(pat, len, plugpat, eap->arg);
do_in_path(p_pp, (char_u *)pat, DIP_ALL, add_pack_plugin, p_pp);
#ifdef FEAT_AUTOCMD
vim_snprintf(pat, len, ftpat, eap->arg);
may_do_filetypes((char_u *)pat);
#endif
vim_free(pat);
}
/*
* ":packadd {name}"
*/ */
void void
ex_packadd(exarg_T *eap) ex_packadd(exarg_T *eap)
@ -3208,7 +3197,8 @@ ex_packadd(exarg_T *eap)
if (pat == NULL) if (pat == NULL)
return; return;
vim_snprintf(pat, len, plugpat, eap->arg); vim_snprintf(pat, len, plugpat, eap->arg);
do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR, add_pack_plugin, NULL); do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR, add_pack_plugin,
eap->forceit ? NULL : p_pp);
vim_free(pat); vim_free(pat);
} }

View File

@ -178,7 +178,7 @@ NEW_TESTS = test_arglist.res \
test_increment.res \ test_increment.res \
test_json.res \ test_json.res \
test_langmap.res \ test_langmap.res \
test_loadplugin.res \ test_packadd.res \
test_perl.res \ test_perl.res \
test_quickfix.res \ test_quickfix.res \
test_syntax.res \ test_syntax.res \

View File

@ -1,4 +1,4 @@
" Tests for :loadplugin " Tests for 'packpath' and :packadd
func SetUp() func SetUp()
let s:topdir = expand('%:h') . '/Xdir' let s:topdir = expand('%:h') . '/Xdir'
@ -10,7 +10,7 @@ func TearDown()
call delete(s:topdir, 'rf') call delete(s:topdir, 'rf')
endfunc endfunc
func Test_loadplugin() func Test_packadd()
call mkdir(s:plugdir . '/plugin', 'p') call mkdir(s:plugdir . '/plugin', 'p')
call mkdir(s:plugdir . '/ftdetect', 'p') call mkdir(s:plugdir . '/ftdetect', 'p')
set rtp& set rtp&
@ -25,7 +25,7 @@ func Test_loadplugin()
call setline(1, 'let g:ftdetect_works = 17') call setline(1, 'let g:ftdetect_works = 17')
wq wq
loadplugin mytest packadd mytest
call assert_equal(42, g:plugin_works) call assert_equal(42, g:plugin_works)
call assert_equal(17, g:ftdetect_works) call assert_equal(17, g:ftdetect_works)
@ -33,16 +33,25 @@ func Test_loadplugin()
call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)') call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
endfunc endfunc
func Test_packadd() func Test_packadd_noload()
call mkdir(s:plugdir . '/plugin', 'p')
call mkdir(s:plugdir . '/syntax', 'p') call mkdir(s:plugdir . '/syntax', 'p')
set rtp& set rtp&
let rtp = &rtp let rtp = &rtp
packadd mytest
exe 'split ' . s:plugdir . '/plugin/test.vim'
call setline(1, 'let g:plugin_works = 42')
wq
let g:plugin_works = 0
packadd! mytest
call assert_true(len(&rtp) > len(rtp)) call assert_true(len(&rtp) > len(rtp))
call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)') call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
call assert_equal(0, g:plugin_works)
" check the path is not added twice " check the path is not added twice
let new_rtp = &rtp let new_rtp = &rtp
packadd mytest packadd! mytest
call assert_equal(new_rtp, &rtp) call assert_equal(new_rtp, &rtp)
endfunc endfunc

View File

@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1486,
/**/ /**/
1485, 1485,
/**/ /**/