vim-patch:7.4.1486

Problem:    ":loadplugin" is not optimal, some people find it confusing.
Solution:   Only use ":packadd" with an optional "!".

f365482736
This commit is contained in:
James McCoy
2016-04-28 22:58:24 -04:00
parent 67d8e58631
commit 2f72f34f04
5 changed files with 106 additions and 100 deletions

View File

@@ -418,6 +418,12 @@ You would now have these files under ~/.local/share/nvim/site:
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 ~/.local/share/nvim/site/pack/my/ever/always
% cd ~/.local/share/nvim/site/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'.
@@ -428,11 +434,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

@@ -1452,12 +1452,6 @@ return {
addr_type=ADDR_LINES, addr_type=ADDR_LINES,
func='ex_loadkeymap', func='ex_loadkeymap',
}, },
{
command='loadplugin',
flags=bit.bor(BANG, FILE1, TRLBAR, SBOXOK, CMDWIN),
addr_type=ADDR_LINES,
func='ex_loadplugin',
},
{ {
command='lockmarks', command='lockmarks',
flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),

View File

@@ -2381,76 +2381,67 @@ int do_in_runtimepath(char_u *name, bool all, DoInRuntimepathCB callback,
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);
} }
// Source filetype detection scripts, if filetype.vim was already done. // Expand wildcards in "pat" and invoke do_source() for each match.
static void may_do_filetypes(char_u *pat) static void source_all_matches(char_u *pat)
{ {
char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); int num_files;
char_u **files;
// 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. for (int i = 0; i < num_files; i++) {
if (cmd != NULL && eval_to_number(cmd) > 0) { (void)do_source(files[i], false, DOSO_NONE);
do_cmdline_cmd("augroup filetypedetect"); }
do_in_path(p_pp, pat, DIP_ALL, source_callback, NULL); FreeWild(num_files, files);
do_cmdline_cmd("augroup END");
} }
xfree(cmd);
} }
static void add_pack_plugin(char_u *fname, void *cookie) static void 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 *new_rtp; char_u *new_rtp;
char_u *ffname = (char_u *)fix_fname((char *)fname); char_u *ffname = (char_u *)fix_fname((char *)fname);
bool load_file = cookie != NULL; bool load_files = cookie != NULL;
if (ffname == NULL) { if (ffname == NULL) {
return; return;
} }
p6 = p5 = p4 = p3 = p2 = p1 = get_past_head(ffname);
if (strstr((char *)p_rtp, (char *)ffname) == NULL) {
// directory not in 'runtimepath', add it
p4 = p3 = p2 = p1 = get_past_head(ffname);
for (p = p1; *p; mb_ptr_adv(p)) { for (p = p1; *p; mb_ptr_adv(p)) {
if (vim_ispathsep_nocolon(*p)) { if (vim_ispathsep_nocolon(*p)) {
p6 = p5; p5 = p4; p4 = p3; p3 = p2; p2 = p1; p1 = p; p4 = p3; p3 = p2; p2 = p1; p1 = p;
} }
} }
// now we have: load_file == true // now we have:
// rtp/pack/name/ever/name/plugin/name.vim
// p6 p5 p4 p3 p2 p1
//
// with load_file == false
// rtp/pack/name/ever/name // rtp/pack/name/ever/name
// p4 p3 p2 p1 // p4 p3 p2 p1
if (load_file) { //
p4 = p6;
}
// find the part up to "pack" in 'runtimepath' // find the part up to "pack" in 'runtimepath'
char_u c = *p4; char_u c = *p4;
*p4 = NUL; *p4 = NUL;
p = (char_u *)strstr((char *)p_rtp, (char *)ffname); char_u *insp = (char_u *)strstr((char *)p_rtp, (char *)ffname);
if (p == NULL) { if (insp == NULL) {
// not found, append at the end // not found, append at the end
p = p_rtp + STRLEN(p_rtp); insp = p_rtp + STRLEN(p_rtp);
} else { } else {
// append after the matching directory. // append after the matching directory.
p += STRLEN(ffname); insp += STRLEN(ffname);
while (*insp != NUL && *insp != ',') {
insp++;
}
} }
*p4 = c; *p4 = c;
if (load_file) {
c = *p2;
*p2 = NUL;
}
if (strstr((char *)p_rtp, (char *)ffname) == NULL) {
// directory not in 'runtimepath', add it
size_t oldlen = STRLEN(p_rtp); size_t oldlen = STRLEN(p_rtp);
size_t addlen = STRLEN(ffname); size_t addlen = STRLEN(ffname);
new_rtp = try_malloc(oldlen + addlen + 1); new_rtp = try_malloc(oldlen + addlen + 1);
if (new_rtp == NULL) { if (new_rtp == NULL) {
*p2 = c; goto theend;
return;
} }
uintptr_t keep = (uintptr_t)(p - p_rtp); uintptr_t keep = (uintptr_t)(insp - p_rtp);
memmove(new_rtp, p_rtp, keep); memmove(new_rtp, p_rtp, keep);
new_rtp[keep] = ','; new_rtp[keep] = ',';
memmove(new_rtp + keep + 1, ffname, addlen + 1); memmove(new_rtp + keep + 1, ffname, addlen + 1);
@@ -2461,39 +2452,44 @@ static void 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);
xfree(new_rtp); xfree(new_rtp);
} }
xfree(ffname);
if (load_file) { if (load_files) {
(void)do_source(fname, false, DOSO_NONE); static const char *plugpat = "%s/plugin/*.vim";
static const char *ftpat = "%s/ftdetect/*.vim";
size_t len = STRLEN(ffname) + STRLEN(ftpat);
char_u *pat = try_malloc(len + 1);
if (pat == NULL) {
goto theend;
} }
vim_snprintf((char *)pat, len, plugpat, ffname);
source_all_matches(pat);
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 (eval_to_number(cmd) > 0) {
do_cmdline_cmd("augroup filetypedetect");
vim_snprintf((char *)pat, len, ftpat, ffname);
source_all_matches(pat);
do_cmdline_cmd("augroup END");
}
xfree(cmd);
}
theend:
xfree(ffname);
} }
// Source the plugins in the package directories. // Find plugins in the package directories and source them.
void source_packages(void) void source_packages(void)
{ {
do_in_path(p_pp, (char_u *)"pack/*/ever/*/plugin/*.vim", do_in_path(p_pp, (char_u *)"pack/*/ever/*", DIP_ALL + DIP_DIR,
DIP_ALL, add_pack_plugin, p_pp); add_pack_plugin, p_pp);
may_do_filetypes((char_u *)"pack/*/ever/*/ftdetect/*.vim");
} }
// ":loadplugin {name}" /// ":packadd[!] {name}"
void ex_loadplugin(exarg_T *eap)
{
static const char *plugpat = "pack/*/opt/%s/plugin/*.vim";
static const char *ftpat = "pack/*/opt/%s/ftdetect/*.vim";
size_t len = STRLEN(ftpat) + STRLEN(eap->arg);
char *pat = xmallocz(len);
vim_snprintf(pat, len, plugpat, eap->arg);
do_in_path(p_pp, (char_u *)pat, DIP_ALL, add_pack_plugin, p_pp);
vim_snprintf(pat, len, ftpat, eap->arg);
may_do_filetypes((char_u *)pat);
xfree(pat);
}
/// ":packadd {name}"
void ex_packadd(exarg_T *eap) void ex_packadd(exarg_T *eap)
{ {
static const char *plugpat = "pack/*/opt/%s"; static const char *plugpat = "pack/*/opt/%s";
@@ -2501,7 +2497,8 @@ void ex_packadd(exarg_T *eap)
size_t len = STRLEN(plugpat) + STRLEN(eap->arg); size_t len = STRLEN(plugpat) + STRLEN(eap->arg);
char *pat = (char *)xmallocz(len); char *pat = (char *)xmallocz(len);
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);
xfree(pat); xfree(pat);
} }

View File

@@ -209,7 +209,7 @@ static int included_patches[] = {
// 1489 NA // 1489 NA
// 1488 NA // 1488 NA
// 1487 NA // 1487 NA
// 1486, 1486,
// 1485 NA // 1485 NA
// 1484 NA // 1484 NA
// 1483 NA // 1483 NA

View File

@@ -1,4 +1,4 @@
-- Tests for :loadplugin -- Tests for 'packpath' and :packadd
local helpers = require('test.functional.helpers')(after_each) local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source local clear, source = helpers.clear, helpers.source
@@ -8,8 +8,8 @@ local function expected_empty()
eq({}, nvim.get_vvar('errors')) eq({}, nvim.get_vvar('errors'))
end end
describe('loadplugin', function() describe('packadd', function()
setup(function() before_each(function()
clear() clear()
source([=[ source([=[
@@ -23,7 +23,7 @@ describe('loadplugin', function()
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&
@@ -38,7 +38,7 @@ describe('loadplugin', function()
call setline(1, 'let g:ftdetect_works = 17') call setline(1, 'let g:ftdetect_works = 17')
wq wq
loadplugin mytest packadd mytest
call assert_true(42, g:plugin_works) call assert_true(42, g:plugin_works)
call assert_true(17, g:ftdetect_works) call assert_true(17, g:ftdetect_works)
@@ -46,34 +46,43 @@ describe('loadplugin', function()
call assert_true(&rtp =~ (s:plugdir . '\($\|,\)')) call assert_true(&rtp =~ (s:plugdir . '\($\|,\)'))
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 =~ (s:plugdir . '\($\|,\)')) call assert_true(&rtp =~ (s:plugdir . '\($\|,\)'))
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
]=]) ]=])
call('SetUp') call('SetUp')
end) end)
teardown(function() after_each(function()
call('TearDown') call('TearDown')
end) end)
it('is working', function() it('is working', function()
call('Test_loadplugin')
expected_empty()
end)
it('works with packadd', function()
call('Test_packadd') call('Test_packadd')
expected_empty() expected_empty()
end) end)
it('works with packadd!', function()
call('Test_packadd_noload')
expected_empty()
end)
end) end)