]> granicus.if.org Git - vim/commitdiff
patch 8.2.0208: fnamemodify() does not apply ":~" when followed by ":." v8.2.0208
authorBram Moolenaar <Bram@vim.org>
Tue, 4 Feb 2020 21:23:09 +0000 (22:23 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 4 Feb 2020 21:23:09 +0000 (22:23 +0100)
Problem:    Fnamemodify() does not apply ":~" when followed by ":.".
Solution:   Don't let a failing ":." cause the ":~" to be skipped. (Yasuhiro
            Matsumoto, closes #5577)

runtime/doc/cmdline.txt
src/filepath.c
src/testdir/test_fnamemodify.vim
src/version.c

index c4638b624bea165f8efff361d3686fc85c129ced..528975675185b6ef29e091aba624984da775ce45 100644 (file)
@@ -933,8 +933,7 @@ These modifiers can be given, in this order:
                directory.
        :.      Reduce file name to be relative to current directory, if
                possible.  File name is unmodified if it is not below the
-               current directory, but on MS-Windows the drive is removed if
-               it is the current drive.
+               current directory.
                For maximum shortness, use ":~:.".
        :h      Head of the file name (the last component and any separators
                removed).  Cannot be used with :e, :r or :t.
index 04026a0986acf32bca7d55fc73cf2abc16c53445..4517f412ce6aa3e15876577e406787ed5d592567 100644 (file)
@@ -301,6 +301,7 @@ modify_fname(
     char_u     dirname[MAXPATHL];
     int                c;
     int                has_fullname = 0;
+    int                has_homerelative = 0;
 #ifdef MSWIN
     char_u     *fname_start = *fnamep;
     int                has_shortname = 0;
@@ -412,7 +413,7 @@ repeat:
        }
        pbuf = NULL;
        // Need full path first (use expand_env() to remove a "~/")
-       if (!has_fullname)
+       if (!has_fullname && !has_homerelative)
        {
            if (c == '.' && **fnamep == '~')
                p = pbuf = expand_env_save(*fnamep);
@@ -428,11 +429,28 @@ repeat:
        {
            if (c == '.')
            {
+               size_t  namelen;
+
                mch_dirname(dirname, MAXPATHL);
-               s = shorten_fname(p, dirname);
-               if (s != NULL)
+               if (has_homerelative)
+               {
+                   s = vim_strsave(dirname);
+                   if (s != NULL)
+                   {
+                       home_replace(NULL, s, dirname, MAXPATHL, TRUE);
+                       vim_free(s);
+                   }
+               }
+               namelen = STRLEN(dirname);
+
+               // Do not call shorten_fname() here since it removes the prefix
+               // even though the path does not have a prefix.
+               if (fnamencmp(p, dirname, namelen) == 0)
                {
-                   *fnamep = s;
+                   p += namelen;
+                   while (*p && vim_ispathsep(*p))
+                       ++p;
+                   *fnamep = p;
                    if (pbuf != NULL)
                    {
                        vim_free(*bufp);   // free any allocated file name
@@ -453,6 +471,7 @@ repeat:
                        *fnamep = s;
                        vim_free(*bufp);
                        *bufp = s;
+                       has_homerelative = TRUE;
                    }
                }
            }
@@ -701,6 +720,7 @@ f_chdir(typval_T *argvars, typval_T *rettv)
     rettv->vval.v_string = NULL;
 
     if (argvars[0].v_type != VAR_STRING)
+       // Returning an empty string means it failed.
        return;
 
     // Return the current directory
index a8324ab8a9e37a6c58ee349fc162ea402d46eeb1..7a21efef836e885592fe393f4c0834ebe6804a63 100644 (file)
@@ -3,8 +3,10 @@
 func Test_fnamemodify()
   let save_home = $HOME
   let save_shell = &shell
+  let save_shellslash = &shellslash
   let $HOME = fnamemodify('.', ':p:h:h')
   set shell=sh
+  set shellslash
 
   call assert_equal('/', fnamemodify('.', ':p')[-1:])
   call assert_equal('r', fnamemodify('.', ':p:h')[-1:])
@@ -28,6 +30,15 @@ func Test_fnamemodify()
   call assert_equal('fb2.tar.gz', fnamemodify('abc.fb2.tar.gz', ':e:e:e:e'))
   call assert_equal('tar', fnamemodify('abc.fb2.tar.gz', ':e:e:r'))
 
+  let cwd = getcwd()
+  call mkdir($HOME . '/XXXXXXXX/a', 'p')
+  call mkdir($HOME . '/XXXXXXXX/b', 'p')
+  call chdir($HOME . '/XXXXXXXX/a/')
+  call assert_equal('foo', fnamemodify($HOME . '/XXXXXXXX/a/foo', ':p:~:.'))
+  call assert_equal('~/XXXXXXXX/b/foo', fnamemodify($HOME . '/XXXXXXXX/b/foo', ':p:~:.'))
+  call chdir(cwd)
+  call delete($HOME . '/XXXXXXXX', 'rf')
+
   call assert_equal('''abc def''', fnamemodify('abc def', ':S'))
   call assert_equal('''abc" "def''', fnamemodify('abc" "def', ':S'))
   call assert_equal('''abc"%"def''', fnamemodify('abc"%"def', ':S'))
@@ -44,6 +55,7 @@ func Test_fnamemodify()
 
   let $HOME = save_home
   let &shell = save_shell
+  let &shellslash = save_shellslash
 endfunc
 
 func Test_fnamemodify_er()
index be1bf33705b08a12f1735c58a9114b9075ef1283..6e598e588304f34ebd72eb85f015e35ed52f5030 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    208,
 /**/
     207,
 /**/