junegunn / fzf

:cherry_blossom: A command-line fuzzy finder
https://junegunn.github.io/fzf/
MIT License
63.4k stars 2.36k forks source link

Use realpath for fzf cd #3688

Closed emivespa closed 5 months ago

emivespa commented 5 months ago

Rationale: this way the resulting cd command that ends up in the shell history can be can be reused to get to the same location regardless of present working directory.

LangLangBart commented 5 months ago

Just a note for macOS.

The realpath command was only included as a default shell command starting with macOS Ventura[^1].

The readlink command, when used with the -f flag, was only included starting with macOS Monterey[^2].

In zsh, one can use the :a or :A (covers symlinks) modifier to achieve similar functionality[^3].

pwd
# /Users/paria
ls -l testing\ dir
# lrwxr-xr-x  1 paria  staff  32 Mar 20 19:50 testing dir -> /Users/paria/Desktop/testing dir
dir="testing dir"
echo ${(q)dir:a}
# /Users/paria/testing\ dir
echo ${(q)dir:A}
# /Users/paria/Desktop/testing\ dir

More techniques are discussed in this issue: Issue #8 · junegunn/fzf-git.sh

[^1]: Apple Open Source [^2]: Some CLI updates in macOS Monterey – Scripting OS X [^3]: zsh: 14 Expansion Modifiers

junegunn commented 5 months ago

@LangLangBart Thanks for reminding me.

@emivespa Thanks, I like the idea, but we should try to make this work even in older versions of macOS. We could use the Ruby or Perl fallback shown in the linked issue for bash and the :a method for zsh as suggested by @LangLangBart.

LangLangBart commented 5 months ago

We could use the Ruby or Perl fallback

As an alternative solution, the following option is fast and popular[^1][^2][^3]

--- a/shell/key-bindings.bash
+++ b/shell/key-bindings.bash
@@ -37,11 +37,13 @@ fzf-file-widget() {
 }

 __fzf_cd__() {
-  local opts dir
+  local opts dir abs_dir
   opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse --walker=dir,follow,hidden --scheme=path ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m"
   dir=$(
     FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} FZF_DEFAULT_OPTS="$opts" $(__fzfcmd)
-  ) && printf 'builtin cd -- %q' "$dir"
+  ) && if abs_dir=$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd);then
+    printf 'builtin cd -- %q' "$abs_dir"
+  fi
 }

 if command -v perl > /dev/null; then

Do you concur with this idea?

[^1]: brew/Library/Homebrew/brew.sh · Homebrew/brew · GitHub [^2]: rust/src/tools/rust-installer/gen-installer.sh at · rust-lang/rust · GitHub [^3]: macos - Bash script absolute path with OS X - Stack Overflow

junegunn commented 5 months ago

@LangLangBart Oh yeah, that's simpler.

junegunn commented 5 months ago
--- a/shell/key-bindings.bash
+++ b/shell/key-bindings.bash
@@ -37,11 +37,13 @@ fzf-file-widget() {
 }

 __fzf_cd__() {
   opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse --walker=dir,follow,hidden --scheme=path ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m"
   dir=$(
     FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} FZF_DEFAULT_OPTS="$opts" $(__fzfcmd)
-  ) && printf 'builtin cd -- %q' "$dir"
+  ) && printf 'builtin cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
 }

 if command -v perl > /dev/null; then
LangLangBart commented 5 months ago
--- a/shell/key-bindings.bash
+++ b/shell/key-bindings.bash
@@ -37,11 +37,13 @@ fzf-file-widget() {
 }

 __fzf_cd__() {
   opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse --walker=dir,follow,hidden --scheme=path ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m"
   dir=$(
     FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} FZF_DEFAULT_OPTS="$opts" $(__fzfcmd)
-  ) && printf 'builtin cd -- %q' "$dir"
+  ) && printf 'builtin cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
 }

 if command -v perl > /dev/null; then

Ok. Will you push it directly, or would you like me to open a PR?

junegunn commented 5 months ago

@LangLangBart Can you comment suggestion diffs on this PR so I can apply them?

junegunn commented 5 months ago

@LangLangBart @emivespa Merged, thanks!