diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-02-07 06:48:10 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-02-07 06:48:10 +0800 |
commit | d457168e3b6078ae018a2b1fe59ff54f82d3ba14 (patch) | |
tree | 543a259bbda316fed82db3b46759f28dbdae5c83 | |
parent | 380bc4fe22e8dbd478e58d568e0d749df439fec9 (diff) | |
download | rneovim-d457168e3b6078ae018a2b1fe59ff54f82d3ba14.tar.gz rneovim-d457168e3b6078ae018a2b1fe59ff54f82d3ba14.tar.bz2 rneovim-d457168e3b6078ae018a2b1fe59ff54f82d3ba14.zip |
vim-patch:8.2.0208: fnamemodify() does not apply ":~" when followed by ":."
Problem: Fnamemodify() does not apply ":~" when followed by ":.".
Solution: Don't let a failing ":." cause the ":~" to be skipped. (Yasuhiro
Matsumoto, closes vim/vim#5577)
https://github.com/vim/vim/commit/d816cd94d87afb73c505bf1e5cd5e07522482113
-rw-r--r-- | runtime/doc/cmdline.txt | 3 | ||||
-rw-r--r-- | src/nvim/eval.c | 28 | ||||
-rw-r--r-- | src/nvim/testdir/test_fnamemodify.vim | 12 |
3 files changed, 34 insertions, 9 deletions
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 641cd93386..f2f6ebb2c9 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -908,8 +908,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. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index dccad5a2d0..70909b46cb 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10624,12 +10624,13 @@ int modify_fname(char_u *src, bool tilde_file, size_t *usedlen, char_u **fnamep, char_u *s, *p, *pbuf; char_u dirname[MAXPATHL]; int c; - int has_fullname = 0; + bool has_fullname = false; + bool has_homerelative = false; repeat: // ":p" - full path/file_name if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') { - has_fullname = 1; + has_fullname = true; valid |= VALID_PATH; *usedlen += 2; @@ -10698,7 +10699,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); } else { @@ -10708,14 +10709,26 @@ repeat: p = *fnamep; } - has_fullname = 0; + has_fullname = false; if (p != NULL) { if (c == '.') { os_dirname(dirname, MAXPATHL); - s = path_shorten_fname(p, dirname); - if (s != NULL) { - *fnamep = s; + if (has_homerelative) { + s = vim_strsave(dirname); + home_replace(NULL, s, dirname, MAXPATHL, true); + xfree(s); + } + size_t 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) { + p += namelen; + while (*p && vim_ispathsep(*p)) { + ++p; + } + *fnamep = p; if (pbuf != NULL) { xfree(*bufp); // free any allocated file name *bufp = pbuf; @@ -10730,6 +10743,7 @@ repeat: *fnamep = s; xfree(*bufp); *bufp = s; + has_homerelative = true; } } xfree(pbuf); diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim index 411f7ebbb3..e8fad397c3 100644 --- a/src/nvim/testdir/test_fnamemodify.vim +++ b/src/nvim/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() |