]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1480 v7.4.1480
authorBram Moolenaar <Bram@vim.org>
Thu, 3 Mar 2016 16:13:03 +0000 (17:13 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 3 Mar 2016 16:13:03 +0000 (17:13 +0100)
Problem:    Cannot add a pack direcory without loading a plugin.
Solution:   Add the :packadd command.

runtime/doc/repeat.txt
src/ex_cmds.h
src/ex_cmds2.c
src/proto/ex_cmds2.pro
src/testdir/test_loadplugin.vim
src/version.c

index 711b1389025a7cabd87d785bfa045e1a384d2177..a6ebf711859d5613dcde166cbd5655178dc57740 100644 (file)
@@ -413,7 +413,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
@@ -443,6 +443,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
index d17f4d54e1046a7f4ad9bc742a2c275ce4098564..94c2816e2a09b7040f282e7b2d00ab44fd881cfc 100644 (file)
@@ -1014,6 +1014,9 @@ EX(CMD_ownsyntax, "ownsyntax",    ex_ownsyntax,
 EX(CMD_print,          "print",        ex_print,
                        RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK,
                        ADDR_LINES),
+EX(CMD_packadd,                "packadd",      ex_packadd,
+                       BANG|FILE1|TRLBAR|SBOXOK|CMDWIN,
+                       ADDR_LINES),
 EX(CMD_pclose,         "pclose",       ex_pclose,
                        BANG|TRLBAR,
                        ADDR_LINES),
index 52575bf0a5b272b77538f00b8c2e4d638fb0c373..73172cb089abaa498233e0875b98be961aa6865a 100644 (file)
@@ -2918,7 +2918,9 @@ source_callback(char_u *fname, void *cookie UNUSED)
 /*
  * 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
@@ -2927,11 +2929,14 @@ source_runtime(char_u *name, int all)
     return do_in_runtimepath(name, all, source_callback, NULL);
 }
 
+#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                all,
+    int                flags,
     void       (*callback)(char_u *fname, void *ck),
     void       *cookie)
 {
@@ -2968,7 +2973,7 @@ do_in_path(
 
        /* Loop over all entries in 'runtimepath'. */
        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, ",");
@@ -2985,7 +2990,7 @@ do_in_path(
 
                /* Loop over all patterns in "name" */
                np = name;
-               while (*np != NUL && (all || !did_one))
+               while (*np != NUL && ((flags & DIP_ALL) || !did_one))
                {
                    /* Append the pattern from "name" to buf[]. */
                    copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
@@ -3000,13 +3005,13 @@ do_in_path(
 
                    /* Expand wildcards, invoke the callback for each match. */
                    if (gen_expand_wildcards(1, &buf, &num_files, &files,
-                                                              EW_FILE) == OK)
+                                 (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;
                        }
                        FreeWild(num_files, files);
@@ -3049,7 +3054,7 @@ do_in_runtimepath(
     void       (*callback)(char_u *fname, void *ck),
     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);
 }
 
 /*
@@ -3065,53 +3070,66 @@ may_do_filetypes(char_u *pat)
     if (cmd != NULL && eval_to_number(cmd) > 0)
     {
        do_cmdline_cmd((char_u *)"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((char_u *)"augroup END");
     }
     vim_free(cmd);
 }
 
     static void
-source_pack_plugin(char_u *fname, void *cookie UNUSED)
+add_pack_plugin(char_u *fname, void *cookie)
 {
-    char_u *p6, *p5, *p4, *p3, *p2, *p1, *p;
-    int c;
-    char_u *new_rtp;
-    int keep;
-    int oldlen;
-    int addlen;
-
-    p6 = p5 = p4 = p3 = p2 = p1 = get_past_head(fname);
+    char_u  *p6, *p5, *p4, *p3, *p2, *p1, *p;
+    int            c;
+    char_u  *new_rtp;
+    int            keep;
+    int            oldlen;
+    int            addlen;
+    char_u  *ffname = fix_fname(fname);
+    int            load_file = cookie != NULL;
+
+    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' */
-    c = *p6;
-    *p6 = NUL;
-    p = (char_u *)strstr((char *)p_rtp, (char *)fname);
+    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);
-    *p6 = c;
+       p += STRLEN(ffname);
+    *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 */
        oldlen = (int)STRLEN(p_rtp);
-       addlen = (int)STRLEN(fname);
+       addlen = (int)STRLEN(ffname);
        new_rtp = alloc(oldlen + addlen + 2);
        if (new_rtp == NULL)
        {
@@ -3121,16 +3139,17 @@ source_pack_plugin(char_u *fname, void *cookie UNUSED)
        keep = (int)(p - p_rtp);
        mch_memmove(new_rtp, p_rtp, keep);
        new_rtp[keep] = ',';
-       mch_memmove(new_rtp + keep + 1, fname, addlen + 1);
+       mch_memmove(new_rtp + keep + 1, ffname, addlen + 1);
        if (p_rtp[keep] != NUL)
            mch_memmove(new_rtp + keep + 1 + addlen, p_rtp + keep,
                                                           oldlen - keep + 1);
        set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
        vim_free(new_rtp);
     }
-    *p2 = c;
+    vim_free(ffname);
 
-    (void)do_source(fname, FALSE, DOSO_NONE);
+    if (load_file)
+       (void)do_source(fname, FALSE, DOSO_NONE);
 }
 
 /*
@@ -3140,7 +3159,7 @@ source_pack_plugin(char_u *fname, void *cookie UNUSED)
 source_packages()
 {
     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");
 }
 
@@ -3160,7 +3179,7 @@ ex_loadplugin(exarg_T *eap)
     if (pat == NULL)
        return;
     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);
@@ -3168,6 +3187,25 @@ ex_loadplugin(exarg_T *eap)
     vim_free(pat);
 }
 
+/*
+ * ":packadd {name}"
+ */
+    void
+ex_packadd(exarg_T *eap)
+{
+    static char *plugpat = "pack/*/opt/%s";
+    int                len;
+    char       *pat;
+
+    len = (int)STRLEN(plugpat) + (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 + DIP_DIR, add_pack_plugin, NULL);
+    vim_free(pat);
+}
+
 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
 /*
  * ":options"
index 3eabcbdb58ed6474a350f4532a8bf5118cb18ae0..e10f072419de1d2e310d2d46928ff994e10434e4 100644 (file)
@@ -64,6 +64,7 @@ int source_runtime(char_u *name, int all);
 int do_in_runtimepath(char_u *name, int all, void (*callback)(char_u *fname, void *ck), void *cookie);
 void source_packages(void);
 void ex_loadplugin(exarg_T *eap);
+void ex_packadd(exarg_T *eap);
 void ex_options(exarg_T *eap);
 void ex_source(exarg_T *eap);
 linenr_T *source_breakpoint(void *cookie);
index 25c67153845a4e28afb0b4cca0b1bc146540fbf1..431dd4a45af1baa8ec673e22c05592d76d9dc5c3 100644 (file)
@@ -1,25 +1,48 @@
 " Tests for :loadplugin
 
+func SetUp()
+  let s:topdir = expand('%: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('%: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_equal(42, g:plugin_works)
+  call assert_equal(17, g:ftdetect_works)
+  call assert_true(len(&rtp) > len(rtp))
+  call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
+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 =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
+
+  " check the path is not added twice
+  let new_rtp = &rtp
+  packadd mytest
+  call assert_equal(new_rtp, &rtp)
 endfunc
index d13f47afa45817f90eb4d1520f98d06abc9fa18c..76ce4620705638ae3987d7df1be5a5ccda88dcb6 100644 (file)
@@ -743,6 +743,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1480,
 /**/
     1479,
 /**/