diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-02-04 22:23:09 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-02-04 22:23:09 +0100 |
commit | d816cd94d87afb73c505bf1e5cd5e07522482113 (patch) | |
tree | 89336db136fc53d20952d0924fa1a33b9e26cf2f /src | |
parent | bfe12043128d75585749f82aebbf4cdd1a7dfe31 (diff) |
patch 8.2.0208: fnamemodify() does not apply ":~" when followed by ":."v8.2.0208
Problem: Fnamemodify() does not apply ":~" when followed by ":.".
Solution: Don't let a failing ":." cause the ":~" to be skipped. (Yasuhiro
Matsumoto, closes #5577)
Diffstat (limited to 'src')
-rw-r--r-- | src/filepath.c | 28 | ||||
-rw-r--r-- | src/testdir/test_fnamemodify.vim | 12 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 38 insertions, 4 deletions
diff --git a/src/filepath.c b/src/filepath.c index 04026a0986..4517f412ce 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -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 diff --git a/src/testdir/test_fnamemodify.vim b/src/testdir/test_fnamemodify.vim index a8324ab8a9..7a21efef83 100644 --- a/src/testdir/test_fnamemodify.vim +++ b/src/testdir/test_fnamemodify.vim @@ -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() diff --git a/src/version.c b/src/version.c index be1bf33705..6e598e5883 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 208, +/**/ 207, /**/ 206, |