patch 9.1.1507: symlinks are resolved on :cd commands Commit: https://github.com/vim/vim/commit/4ade668fb62ebf3f8be537fe451caed6bd1eba9a Author: glepnir <glephun...@gmail.com> Date: Thu Jul 3 20:41:23 2025 +0200
patch 9.1.1507: symlinks are resolved on :cd commands Problem: File paths change from symlink to target path after :cd command when editing files through symbolic links Solution: Add "~" flag to 'cpoptions' to control symlink resolution. When not included (default), symlinks are resolved maintaining backward compatibility. When included, symlinks are preserved providing the improved behavior. (glepnir) related: neovim/neovim#15695 closes: #17628 Signed-off-by: glepnir <glephun...@gmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index b3c5697cf..cf064e17f 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.1. Last change: 2025 Jul 01 +*options.txt* For Vim version 9.1. Last change: 2025 Jul 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2390,7 +2390,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'cpoptions'* *'cpo'* *cpo* 'cpoptions' 'cpo' string (Vim default: "aABceFsz", - Vi default: all flags, except "#{|&/\." + Vi default: all flags, except "#{|&/\.~" |$VIM_POSIX|: all flags) global A sequence of single character flags. When a character is present @@ -2680,6 +2680,13 @@ A jump table for the options with a short description can be found at |Q_op|. character, the cursor won't move. When not included, the cursor would skip over it and jump to the following occurrence. + *cpo-~* + ~ When included, don't resolve symbolic links when + changing directory with |:cd|, |:lcd|, or |:tcd|. + This preserves the symbolic link path in buffer names + and when displaying the current directory. When + excluded (default), symbolic links are resolved to + their target paths. POSIX flags. These are not included in the Vi default value, except when $VIM_POSIX was set on startup. |posix| diff --git a/runtime/doc/tags b/runtime/doc/tags index 71a961697..6b363dbaa 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -6795,6 +6795,7 @@ cpo-x options.txt /*cpo-x* cpo-y options.txt /*cpo-y* cpo-z options.txt /*cpo-z* cpo-{ options.txt /*cpo-{* +cpo-~ options.txt /*cpo-~* cpp.vim syntax.txt /*cpp.vim* crash-recovery recover.txt /*crash-recovery* creating-menus gui.txt /*creating-menus* diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index fcd3b9f34..75d14011a 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -41643,6 +41643,8 @@ Options: ~ - 'completeopt' is now a |global-local| option. - add 'cpoptions' flag "z" |cpo-z|, to disable some (traditional) vi behaviour/inconsistency (see |d-special| and |cw|). +- add 'cpoptions' flag "~" |cpo-~| to disable resolving symlinks on |:cd| + commands - new option values for 'fillchars': "trunc" - configure truncation indicator, 'pummaxwidth' "truncrl" - like "trunc" but in 'rl' mode, 'pummaxwidth' diff --git a/src/ex_docmd.c b/src/ex_docmd.c index ba0bff466..b985e2ba2 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8029,7 +8029,7 @@ post_chdir(cdscope_T scope) } last_chdir_reason = NULL; - shorten_fnames(TRUE); + shorten_fnames(vim_strchr(p_cpo, CPO_NOSYMLINKS) == NULL); } /* diff --git a/src/option.h b/src/option.h index 4ed117c70..5590e5635 100644 --- a/src/option.h +++ b/src/option.h @@ -231,10 +231,11 @@ typedef enum { #define CPO_CHDIR '.' // don't chdir if buffer is modified #define CPO_SCOLON ';' // using "," and ";" will skip over char if // cursor would not move +#define CPO_NOSYMLINKS '~' // don't resolve symlinks when changing directory // default values for Vim, Vi and POSIX #define CPO_VIM "aABceFsz" #define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;" -#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;" +#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;~" // characters for p_ww option: #define WW_ALL "bshl<>[]~" diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim index 13a3eba37..85494d386 100644 --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -252,4 +252,67 @@ func Test_getcwd_actual_dir() call chdir(startdir) endfunc +func Test_cd_preserve_symlinks() + " Test new behavior: preserve symlinks when cpo-=~ + set cpoptions+=~ + + let savedir = getcwd() + call mkdir('Xsource', 'R') + call writefile(['abc'], 'Xsource/foo.txt', 'D') + + if has("win32") + silent !mklink /D Xdest Xsource + else + silent !ln -s Xsource Xdest + endif + if v:shell_error + call delete('Xsource', 'rf') + throw 'Skipped: cannot create symlinks' + endif + + edit Xdest/foo.txt + let path_before = expand('%') + call assert_match('Xdest[/\]foo\.txt$', path_before) + + cd . + let path_after = expand('%') + call assert_equal(path_before, path_after) + call assert_match('Xdest[/\]foo\.txt$', path_after) + + bwipe! + set cpoptions& + call delete('Xdest', 'rf') + call delete('Xsource', 'rf') + call chdir(savedir) +endfunc + +func Test_cd_symlinks() + CheckNotMSWindows + + let savedir = getcwd() + call mkdir('Xsource', 'R') + call writefile(['abc'], 'Xsource/foo.txt', 'D') + + silent !ln -s Xsource Xdest + if v:shell_error + call delete('Xsource', 'rf') + throw 'Skipped: cannot create symlinks' + endif + + edit Xdest/foo.txt + let path_before = expand('%') + call assert_match('Xdest[/\]foo\.txt$', path_before) + + cd . + let path_after = expand('%') + call assert_match('Xsource[/\]foo\.txt$', path_after) + call assert_notequal(path_before, path_after) + + bwipe! + set cpoptions& + call delete('Xdest', 'rf') + call delete('Xsource', 'rf') + call chdir(savedir) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index cb5636ee1..21e4a0357 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -2273,7 +2273,7 @@ func Test_VIM_POSIX() qall [CODE] if RunVim([], after, '') - call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;', + call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;~', \ 'AS'], readfile('X_VIM_POSIX')) endif @@ -2528,7 +2528,7 @@ func Test_string_option_revert_on_failure() \ ['completeopt', 'popup', 'a123'], \ ['completepopup', 'width:20', 'border'], \ ['concealcursor', 'v', 'xyz'], - \ ['cpoptions', 'HJ', '~'], + \ ['cpoptions', 'HJ', 'Q'], \ ['cryptmethod', 'zip', 'a123'], \ ['cursorlineopt', 'screenline', 'a123'], \ ['debug', 'throw', 'a123'], diff --git a/src/version.c b/src/version.c index d5a882da6..9d2768168 100644 --- a/src/version.c +++ b/src/version.c @@ -719,6 +719,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1507, /**/ 1506, /**/ -- -- 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. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uXPAD-001Hlh-Sb%40256bit.org.