0
0
mirror of https://github.com/vim/vim.git synced 2025-07-04 23:07:33 -04:00

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 <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir 2025-07-03 20:41:23 +02:00 committed by Christian Brabandt
parent 0d50d6089d
commit 4ade668fb6
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
8 changed files with 82 additions and 6 deletions

View File

@ -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|

View File

@ -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*

View File

@ -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'

View File

@ -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);
}
/*

View File

@ -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<>[]~"

View File

@ -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

View File

@ -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'],

View File

@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1507,
/**/
1506,
/**/