[shell][zsh] Don't resolve symlinks in ALT-c (#4816)

This way ALT-c behaves more aligned with `cd`.

Imagine a setup like:
```
/foo -> foo_real
/foo_real/bar
```

Right now if we first `cd foo` (a symlink to `foo_real`), and
then use ALT-c to goto `bar`, then we would end up executing
`cd /foo_real/bar` instead of `cd /foo/bar`. `$PWD = /foo_real/bar`.

For comparison, if we first `cd foo` and then `cd bar`, we end up with
`$PWD = /foo/bar`.

This commit changes the internal logic of `fzf-cd-widget` to first run
`cd <result of FZF_ALT_C_COMMAND>` in a subshell to simulate the
behavior of `cd`, and then insert the target PWD into the shell history.
This way we get behavior consistent with the builtin `cd` command, while
also recording reusable shell history.
This commit is contained in:
Yi-Yo Chiang
2026-05-30 00:40:40 +08:00
committed by Junegunn Choi
parent 6bd17f8f9a
commit 7d647c70c2
+7 -1
View File
@@ -110,8 +110,14 @@ fzf-cd-widget() {
zle redisplay zle redisplay
return 0 return 0
fi fi
# Use subshell expansion to get the absolute PWD of the target dir.
# This allows the recorded shell history to be reused even from a different
# working directory.
# If failed, fallback to the unexpanded path to surface the error to the user.
# NOTE: Don't use the `:a` modifier as it resolves symlinks like `pwd -P`.
dir=$(builtin cd >/dev/null -- "${dir}" && echo "${PWD}" || echo "${dir}")
zle push-line # Clear buffer. Auto-restored on next prompt. zle push-line # Clear buffer. Auto-restored on next prompt.
BUFFER="builtin cd -- ${(q)dir:a}" BUFFER="builtin cd -- ${(q)dir}"
zle accept-line zle accept-line
local ret=$? local ret=$?
unset dir # ensure this doesn't end up appearing in prompt expansion unset dir # ensure this doesn't end up appearing in prompt expansion