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/filepath.c | |
parent | bfe12043128d75585749f82aebbf4cdd1a7dfe31 (diff) | |
download | vim-git-d816cd94d87afb73c505bf1e5cd5e07522482113.tar.gz |
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/filepath.c')
-rw-r--r-- | src/filepath.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/filepath.c b/src/filepath.c index 04026a098..4517f412c 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 |