Patch 8.0.1469
Problem:    When package path is a symlink adding it to 'runtimepath' happens
            at the end.
Solution:   Do not resolve symlinks before locating the position in
            'runtimepath'. (Ozaki Kiichi, closes #2604)
Files:      src/ex_cmds2.c, src/testdir/test_packadd.vim


*** ../vim-8.0.1468/src/ex_cmds2.c      2017-12-17 14:26:40.818477607 +0100
--- src/ex_cmds2.c      2018-02-04 17:40:02.833263894 +0100
***************
*** 3567,3579 ****
      }
  }
  
! /* used for "cookie" of add_pack_plugin() */
! static int APP_ADD_DIR;
! static int APP_LOAD;
! static int APP_BOTH;
! 
!     static void
! add_pack_plugin(char_u *fname, void *cookie)
  {
      char_u  *p4, *p3, *p2, *p1, *p;
      char_u  *insp;
--- 3567,3577 ----
      }
  }
  
! /*
!  * Add the package directory to 'runtimepath'.
!  */
!     static int
! add_pack_dir_to_rtp(char_u *fname)
  {
      char_u  *p4, *p3, *p2, *p1, *p;
      char_u  *insp;
***************
*** 3582,3706 ****
      int           keep;
      size_t  oldlen;
      size_t  addlen;
!     char_u  *afterdir;
      size_t  afterlen = 0;
!     char_u  *ffname = fix_fname(fname);
      size_t  fname_len;
      char_u  *buf = NULL;
      char_u  *rtp_ffname;
      int           match;
  
!     if (ffname == NULL)
!       return;
!     if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL)
!     {
!       /* directory is not yet 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/start/name
!        *    p4   p3   p2    p1
!        *
!        * find the part up to "pack" in 'runtimepath' */
!       c = *p4;
!       *p4 = NUL;
! 
!       /* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
!       fname_len = STRLEN(ffname);
!       insp = p_rtp;
!       buf = alloc(MAXPATHL);
!       if (buf == NULL)
!           goto theend;
!       while (*insp != NUL)
        {
!           copy_option_part(&insp, buf, MAXPATHL, ",");
!           add_pathsep(buf);
!           rtp_ffname = fix_fname(buf);
!           if (rtp_ffname == NULL)
!               goto theend;
!           match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
!           vim_free(rtp_ffname);
!           if (match)
!               break;
        }
  
!       if (*insp == NUL)
!           /* not found, append at the end */
!           insp = p_rtp + STRLEN(p_rtp);
!       else
!           /* append after the matching directory. */
!           --insp;
!       *p4 = c;
! 
!       /* check if rtp/pack/name/start/name/after exists */
!       afterdir = concat_fnames(ffname, (char_u *)"after", TRUE);
!       if (afterdir != NULL && mch_isdir(afterdir))
!           afterlen = STRLEN(afterdir) + 1; /* add one for comma */
! 
!       oldlen = STRLEN(p_rtp);
!       addlen = STRLEN(ffname) + 1; /* add one for comma */
!       new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
!                                                         /* add one for NUL */
!       if (new_rtp == NULL)
            goto theend;
!       keep = (int)(insp - p_rtp);
!       mch_memmove(new_rtp, p_rtp, keep);
!       new_rtp[keep] = ',';
!       mch_memmove(new_rtp + keep + 1, ffname, addlen);
!       if (p_rtp[keep] != NUL)
!           mch_memmove(new_rtp + keep + addlen, p_rtp + keep,
!                                                          oldlen - keep + 1);
!       if (afterlen > 0)
!       {
!           STRCAT(new_rtp, ",");
!           STRCAT(new_rtp, afterdir);
!       }
!       set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
!       vim_free(new_rtp);
!       vim_free(afterdir);
      }
  
!     if (cookie != &APP_ADD_DIR)
      {
!       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
!       vim_free(pat);
      }
  
  theend:
-     vim_free(buf);
      vim_free(ffname);
  }
  
  /*
--- 3580,3733 ----
      int           keep;
      size_t  oldlen;
      size_t  addlen;
!     char_u  *afterdir = NULL;
      size_t  afterlen = 0;
!     char_u  *ffname = NULL;
      size_t  fname_len;
      char_u  *buf = NULL;
      char_u  *rtp_ffname;
      int           match;
+     int           retval = FAIL;
  
!     p4 = p3 = p2 = p1 = get_past_head(fname);
!     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/start/name
!      *    p4   p3   p2    p1
!      *
!      * find the part up to "pack" in 'runtimepath' */
!     c = *++p4; /* append pathsep in order to expand symlink */
!     *p4 = NUL;
!     ffname = fix_fname(fname);
!     *p4 = c;
!     if (ffname == NULL)
!       return FAIL;
! 
!     /* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
!     fname_len = STRLEN(ffname);
!     insp = p_rtp;
!     buf = alloc(MAXPATHL);
!     if (buf == NULL)
!       goto theend;
!     while (*insp != NUL)
!     {
!       copy_option_part(&insp, buf, MAXPATHL, ",");
!       add_pathsep(buf);
!       rtp_ffname = fix_fname(buf);
!       if (rtp_ffname == NULL)
            goto theend;
!       match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
!       vim_free(rtp_ffname);
!       if (match)
!           break;
      }
  
!     if (*insp == NUL)
!       /* not found, append at the end */
!       insp = p_rtp + STRLEN(p_rtp);
!     else
!       /* append after the matching directory. */
!       --insp;
! 
!     /* check if rtp/pack/name/start/name/after exists */
!     afterdir = concat_fnames(fname, (char_u *)"after", TRUE);
!     if (afterdir != NULL && mch_isdir(afterdir))
!       afterlen = STRLEN(afterdir) + 1; /* add one for comma */
! 
!     oldlen = STRLEN(p_rtp);
!     addlen = STRLEN(fname) + 1; /* add one for comma */
!     new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
!     /* add one for NUL */
!     if (new_rtp == NULL)
!       goto theend;
!     keep = (int)(insp - p_rtp);
!     mch_memmove(new_rtp, p_rtp, keep);
!     new_rtp[keep] = ',';
!     mch_memmove(new_rtp + keep + 1, fname, addlen);
!     if (p_rtp[keep] != NUL)
!       mch_memmove(new_rtp + keep + addlen, p_rtp + keep, oldlen - keep + 1);
!     if (afterlen > 0)
      {
!       STRCAT(new_rtp, ",");
!       STRCAT(new_rtp, afterdir);
!     }
!     set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
!     vim_free(new_rtp);
!     retval = OK;
! 
! theend:
!     vim_free(buf);
!     vim_free(ffname);
!     vim_free(afterdir);
!     return retval;
! }
! 
! /*
!  * Load scripts in "plugin" and "ftdetect" directories of the package.
!  */
!     static int
! load_pack_plugin(char_u *fname)
! {
!     static char *plugpat = "%s/plugin/**/*.vim";
!     static char *ftpat = "%s/ftdetect/*.vim";
!     int               len;
!     char_u    *ffname = fix_fname(fname);
!     char_u    *pat = NULL;
!     int               retval = FAIL;
! 
!     if (ffname == NULL)
!       return FAIL;
!     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
+     vim_free(pat);
+     retval = OK;
  
  theend:
      vim_free(ffname);
+     return retval;
+ }
+ 
+ /* used for "cookie" of add_pack_plugin() */
+ static int APP_ADD_DIR;
+ static int APP_LOAD;
+ static int APP_BOTH;
+ 
+     static void
+ add_pack_plugin(char_u *fname, void *cookie)
+ {
+     if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)fname) == NULL)
+       /* directory is not yet in 'runtimepath', add it */
+       if (add_pack_dir_to_rtp(fname) == FAIL)
+           return;
+ 
+     if (cookie != &APP_ADD_DIR)
+       load_pack_plugin(fname);
  }
  
  /*
*** ../vim-8.0.1468/src/testdir/test_packadd.vim        2017-12-17 
14:26:40.818477607 +0100
--- src/testdir/test_packadd.vim        2018-02-04 17:28:36.066503738 +0100
***************
*** 37,44 ****
    call assert_equal(77, g:plugin_also_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\($\|,\)')
!   call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/opt/mytest/after$')
  
    " Check exception
    call assert_fails("packadd directorynotfound", 'E919:')
--- 37,44 ----
    call assert_equal(77, g:plugin_also_works)
    call assert_equal(17, g:ftdetect_works)
    call assert_true(len(&rtp) > len(rtp))
!   call assert_match('/testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
!   call assert_match('/testdir/Xdir/pack/mine/opt/mytest/after$', &rtp)
  
    " Check exception
    call assert_fails("packadd directorynotfound", 'E919:')
***************
*** 60,66 ****
  
    call assert_equal(24, g:plugin_works)
    call assert_true(len(&rtp) > len(rtp))
!   call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/start/other\($\|,\)')
  endfunc
  
  func Test_packadd_noload()
--- 60,66 ----
  
    call assert_equal(24, g:plugin_works)
    call assert_true(len(&rtp) > len(rtp))
!   call assert_match('/testdir/Xdir/pack/mine/start/other\($\|,\)', &rtp)
  endfunc
  
  func Test_packadd_noload()
***************
*** 77,83 ****
    packadd! mytest
  
    call assert_true(len(&rtp) > len(rtp))
!   call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
    call assert_equal(0, g:plugin_works)
  
    " check the path is not added twice
--- 77,83 ----
    packadd! mytest
  
    call assert_true(len(&rtp) > len(rtp))
!   call assert_match('testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
    call assert_equal(0, g:plugin_works)
  
    " check the path is not added twice
***************
*** 108,114 ****
    packadd mytest
  
    " Must have been inserted in the middle, not at the end
!   call assert_true(&rtp =~ '/pack/mine/opt/mytest,')
    call assert_equal(44, g:plugin_works)
  
    " No change when doing it again.
--- 108,114 ----
    packadd mytest
  
    " Must have been inserted in the middle, not at the end
!   call assert_match('/pack/mine/opt/mytest,', &rtp)
    call assert_equal(44, g:plugin_works)
  
    " No change when doing it again.
***************
*** 121,126 ****
--- 121,163 ----
    exec "silent !rm" top2_dir
  endfunc
  
+ func Test_packadd_symlink_dir2()
+   if !has('unix')
+     return
+   endif
+   let top2_dir = s:topdir . '/Xdir2'
+   let real_dir = s:topdir . '/Xsym/pack'
+   call mkdir(top2_dir, 'p')
+   call mkdir(real_dir, 'p')
+   let &rtp = top2_dir . ',' . top2_dir . '/after'
+   let &packpath = &rtp
+ 
+   exec "silent !ln -s ../Xsym/pack"  top2_dir . '/pack'
+   let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
+   call mkdir(s:plugdir . '/plugin', 'p')
+ 
+   exe 'split ' . s:plugdir . '/plugin/test.vim'
+   call setline(1, 'let g:plugin_works = 48')
+   wq
+   let g:plugin_works = 0
+ 
+   packadd mytest
+ 
+   " Must have been inserted in the middle, not at the end
+   call assert_match('/Xdir2/pack/mine/opt/mytest,', &rtp)
+   call assert_equal(48, g:plugin_works)
+ 
+   " No change when doing it again.
+   let rtp_before = &rtp
+   packadd mytest
+   call assert_equal(rtp_before, &rtp)
+ 
+   set rtp&
+   let rtp = &rtp
+   exec "silent !rm" top2_dir . '/pack'
+   exec "silent !rmdir" top2_dir
+ endfunc
+ 
  " Check command-line completion for 'packadd'
  func Test_packadd_completion()
    let optdir1 = &packpath . '/pack/mine/opt'
***************
*** 196,204 ****
    helptags ALL
  
    let tags1 = readfile(docdir1 . '/tags') 
!   call assert_true(tags1[0] =~ 'look-here')
    let tags2 = readfile(docdir2 . '/tags') 
!   call assert_true(tags2[0] =~ 'look-away')
  endfunc
  
  func Test_colorscheme()
--- 233,241 ----
    helptags ALL
  
    let tags1 = readfile(docdir1 . '/tags') 
!   call assert_match('look-here', tags1[0])
    let tags2 = readfile(docdir2 . '/tags') 
!   call assert_match('look-away', tags2[0])
  endfunc
  
  func Test_colorscheme()
*** ../vim-8.0.1468/src/version.c       2018-02-04 16:38:41.755315266 +0100
--- src/version.c       2018-02-04 17:30:33.597690378 +0100
***************
*** 773,774 ****
--- 773,776 ----
  {   /* Add new patch number below this line */
+ /**/
+     1469,
  /**/

-- 
You had connectors?  Eeee, when I were a lad we 'ad to carry the
bits between the computer and the terminal with a spoon...

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui