diff options
author | James McCoy <jamessan@jamessan.com> | 2016-04-28 20:47:27 -0400 |
---|---|---|
committer | James McCoy <jamessan@jamessan.com> | 2016-07-08 01:43:30 -0400 |
commit | 67d8e586318a3f2f13df22f9a3b25c6d8a109e6c (patch) | |
tree | 4eef691cf90cee6144e0cec7b8f56f33629cb8bc | |
parent | d43ac790f2454e2173eb645bdcd97c7a7c7e4846 (diff) | |
download | rneovim-67d8e586318a3f2f13df22f9a3b25c6d8a109e6c.tar.gz rneovim-67d8e586318a3f2f13df22f9a3b25c6d8a109e6c.tar.bz2 rneovim-67d8e586318a3f2f13df22f9a3b25c6d8a109e6c.zip |
vim-patch:7.4.1480
Problem: Cannot add a pack direcory without loading a plugin.
Solution: Add the :packadd command.
https://github.com/vim/vim/commit/91715873d19a1859c08eeded7848113596e2f2bd
-rw-r--r-- | runtime/doc/repeat.txt | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 6 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 86 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/functional/legacy/loadplugin_spec.lua | 73 |
5 files changed, 123 insertions, 48 deletions
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 527b84c992..b9dee8d261 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -398,7 +398,7 @@ A Vim package is a directory that contains one or more plugins. The advantages over normal plugins: - A package can be downloaded as an archive and unpacked in its own directory. That makes it easy to updated and/or remove. -- A package can be a git, mercurial, etc. respository. That makes it really +- A package can be a git, mercurial, etc. repository. That makes it really easy to update. - A package can contain multiple plugins that depend on each other. - A package can contain plugins that are automatically loaded on startup and @@ -428,6 +428,8 @@ 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 find the syntax/always.vim file, because its directory is in 'runtimepath'. +Vim will also load ftdetect files, like with |:loadplugin|. + *load-plugin* To load an optional plugin from a pack use the `:loadplugin` command: > :loadplugin mydebug diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 7bfb592ea7..de538ce733 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1855,6 +1855,12 @@ return { func='ex_print', }, { + command='packadd', + flags=bit.bor(BANG, FILE1, TRLBAR, SBOXOK, CMDWIN), + addr_type=ADDR_LINES, + func='ex_packadd', + }, + { command='pclose', flags=bit.bor(BANG, TRLBAR), addr_type=ADDR_LINES, diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index bafd4ee666..93da08a629 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2277,14 +2277,19 @@ static void source_callback(char_u *fname, void *cookie) /// Source the file "name" from all directories in 'runtimepath'. /// "name" can contain wildcards. -/// When "all" is true, source all files, otherwise only the first one. +/// When "flags" has DIP_ALL: source all files, otherwise only the first one. +/// When "flags" has DIP_DIR: find directories instead of files. +/// /// return FAIL when no file could be sourced, OK otherwise. int source_runtime(char_u *name, int all) { return do_in_runtimepath(name, all, source_callback, NULL); } -static int do_in_path(char_u *path, char_u *name, bool all, +#define DIP_ALL 1 // all matches, not just the first one +#define DIP_DIR 2 // find directories instead of files. + +static int do_in_path(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback, void *cookie) { char_u *tail; @@ -2307,7 +2312,7 @@ static int do_in_path(char_u *path, char_u *name, bool all, // Loop over all entries in 'runtimepath'. char_u *rtp = rtp_copy; - while (*rtp != NUL && (all || !did_one)) { + while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) { // Copy the path from 'runtimepath' to buf[]. copy_option_part(&rtp, buf, MAXPATHL, ","); if (name == NULL) { @@ -2321,7 +2326,7 @@ static int do_in_path(char_u *path, char_u *name, bool all, // Loop over all patterns in "name" char_u *np = name; - while (*np != NUL && (all || !did_one)) { + while (*np != NUL && ((flags & DIP_ALL) || !did_one)) { // Append the pattern from "name" to buf[]. assert(MAXPATHL >= (tail - buf)); copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)), @@ -2335,11 +2340,12 @@ static int do_in_path(char_u *path, char_u *name, bool all, // Expand wildcards, invoke the callback for each match. if (gen_expand_wildcards(1, &buf, &num_files, &files, - EW_FILE) == OK) { - for (i = 0; i < num_files; i++) { + (flags & DIP_DIR) ? EW_DIR + : EW_FILE) == OK) { + for (i = 0; i < num_files; ++i) { (*callback)(files[i], cookie); did_one = true; - if (!all) { + if (!(flags & DIP_ALL)) { break; } } @@ -2372,7 +2378,7 @@ static int do_in_path(char_u *path, char_u *name, bool all, int do_in_runtimepath(char_u *name, bool all, DoInRuntimepathCB callback, void *cookie) { - return do_in_path(p_rtp, name, all, 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. @@ -2384,47 +2390,61 @@ static void may_do_filetypes(char_u *pat) // when it loads. if (cmd != NULL && eval_to_number(cmd) > 0) { do_cmdline_cmd("augroup filetypedetect"); - do_in_path(p_pp, pat, true, source_callback, NULL); + do_in_path(p_pp, pat, DIP_ALL, source_callback, NULL); do_cmdline_cmd("augroup END"); } xfree(cmd); } -static void source_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 *new_rtp; + char_u *ffname = (char_u *)fix_fname((char *)fname); + bool load_file = cookie != NULL; - p6 = p5 = p4 = p3 = p2 = p1 = get_past_head(fname); + if (ffname == NULL) { + 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: + // 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' - char_u c = *p6; - *p6 = NUL; - p = (char_u *)strstr((char *)p_rtp, (char *)fname); + char_u 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(fname); + p += STRLEN(ffname); } - *p6 = c; + *p4 = c; - c = *p2; - *p2 = NUL; - if (strstr((char *)p_rtp, (char *)fname) == NULL) { + 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 addlen = STRLEN(fname); + size_t addlen = STRLEN(ffname); new_rtp = try_malloc(oldlen + addlen + 1); if (new_rtp == NULL) { *p2 = c; @@ -2433,7 +2453,7 @@ static void source_pack_plugin(char_u *fname, void *cookie) uintptr_t keep = (uintptr_t)(p - p_rtp); memmove(new_rtp, p_rtp, keep); new_rtp[keep] = ','; - memmove(new_rtp + keep + 1, fname, addlen + 1); + memmove(new_rtp + keep + 1, ffname, addlen + 1); if (p_rtp[keep] != NUL) { memmove(new_rtp + keep + 1 + addlen, p_rtp + keep, oldlen - keep + 1); @@ -2441,16 +2461,18 @@ static void source_pack_plugin(char_u *fname, void *cookie) set_option_value((char_u *)"rtp", 0L, new_rtp, 0); xfree(new_rtp); } - *p2 = c; + xfree(ffname); - (void)do_source(fname, false, DOSO_NONE); + if (load_file) { + (void)do_source(fname, false, DOSO_NONE); + } } // Source the plugins in the package directories. void source_packages(void) { do_in_path(p_pp, (char_u *)"pack/*/ever/*/plugin/*.vim", - true, source_pack_plugin, NULL); + DIP_ALL, add_pack_plugin, p_pp); may_do_filetypes((char_u *)"pack/*/ever/*/ftdetect/*.vim"); } @@ -2463,7 +2485,7 @@ void ex_loadplugin(exarg_T *eap) 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, true, source_pack_plugin, NULL); + 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); @@ -2471,6 +2493,18 @@ void ex_loadplugin(exarg_T *eap) xfree(pat); } +/// ":packadd {name}" +void ex_packadd(exarg_T *eap) +{ + static const char *plugpat = "pack/*/opt/%s"; + + size_t len = STRLEN(plugpat) + STRLEN(eap->arg); + char *pat = (char *)xmallocz(len); + vim_snprintf(pat, len, plugpat, eap->arg); + do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR, add_pack_plugin, NULL); + xfree(pat); +} + /// ":options" void ex_options(exarg_T *eap) { diff --git a/src/nvim/version.c b/src/nvim/version.c index da717b9319..4320190592 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -215,7 +215,7 @@ static int included_patches[] = { // 1483 NA // 1482 NA // 1481 NA - // 1480, + 1480, 1479, 1478, // 1477, diff --git a/test/functional/legacy/loadplugin_spec.lua b/test/functional/legacy/loadplugin_spec.lua index 267520ac5c..af97db3ae5 100644 --- a/test/functional/legacy/loadplugin_spec.lua +++ b/test/functional/legacy/loadplugin_spec.lua @@ -13,34 +13,67 @@ describe('loadplugin', function() clear() source([=[ + func SetUp() + let s:topdir = expand('%:p:h') . '/Xdir' + exe 'set packpath=' . s:topdir + let s:plugdir = s:topdir . '/pack/mine/opt/mytest' + endfunc + + func TearDown() + call delete(s:topdir, 'rf') + endfunc + func Test_loadplugin() - let topdir = expand('%:p:h') . '/Xdir' - exe 'set packpath=' . topdir - let plugdir = topdir . '/pack/mine/opt/mytest' - call mkdir(plugdir . '/plugin', 'p') - call mkdir(plugdir . '/ftdetect', 'p') + call mkdir(s:plugdir . '/plugin', 'p') + call mkdir(s:plugdir . '/ftdetect', 'p') + set rtp& + let rtp = &rtp filetype on - try - exe 'split ' . plugdir . '/plugin/test.vim' - call setline(1, 'let g:plugin_works = 42') - wq - - exe 'split ' . plugdir . '/ftdetect/test.vim' - call setline(1, 'let g:ftdetect_works = 17') - wq - - loadplugin mytest - call assert_true(42, g:plugin_works) - call assert_true(17, g:ftdetect_works) - finally - call delete(topdir, 'rf') - endtry + + exe 'split ' . s:plugdir . '/plugin/test.vim' + call setline(1, 'let g:plugin_works = 42') + wq + + exe 'split ' . s:plugdir . '/ftdetect/test.vim' + call setline(1, 'let g:ftdetect_works = 17') + wq + + loadplugin mytest + + call assert_true(42, g:plugin_works) + call assert_true(17, g:ftdetect_works) + call assert_true(len(&rtp) > len(rtp)) + call assert_true(&rtp =~ (s:plugdir . '\($\|,\)')) + endfunc + + func Test_packadd() + call mkdir(s:plugdir . '/syntax', 'p') + set rtp& + let rtp = &rtp + packadd mytest + call assert_true(len(&rtp) > len(rtp)) + call assert_true(&rtp =~ (s:plugdir . '\($\|,\)')) + + " check the path is not added twice + let new_rtp = &rtp + packadd mytest + call assert_equal(new_rtp, &rtp) endfunc ]=]) + call('SetUp') + end) + + teardown(function() + call('TearDown') end) it('is working', function() call('Test_loadplugin') expected_empty() end) + + it('works with packadd', function() + call('Test_packadd') + expected_empty() + end) end) |