Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding to move search root to parent? #4186

Open
5 of 10 tasks
akriegman opened this issue Jan 17, 2025 · 3 comments
Open
5 of 10 tasks

Binding to move search root to parent? #4186

akriegman opened this issue Jan 17, 2025 · 3 comments

Comments

@akriegman
Copy link

Checklist

  • I have read through the manual page (man fzf)
  • I have searched through the existing issues
  • For bug reports, I have checked if the bug is reproducible in the latest version of fzf

Output of fzf --version

0.57.0 (0476a65)

OS

  • Linux
  • macOS
  • Windows
  • Etc.

Shell

  • bash
  • zsh
  • fish

Problem / Steps to reproduce

Feature request: a binding to change the search root to the parent folder.
Use case: sometimes I enter fzf with alt-c or ctrl-t, and I then realize that the folder that I'm looking for is an ancestor or cousin. I then have to ctrl-c, cd ../.., and try again. It would be cool if there was a binding to restart fzf with .. as the new search root to make this quicker. My suggestion is alt-left because that's the binding for back in most browsers.

I think this can be hacked together using the existing very powerful binding features, but I wanted to suggest making this a default binding since it would be really useful in a common use case.

@DanSM-5
Copy link
Contributor

DanSM-5 commented Jan 17, 2025

You can add a bind in FZF_ALT_C_OPTS to allow moving to a fix directory like this:

export FZF_ALT_C_OPTS="
    --bind "ctrl-u:reload(find .. -type d)"
"

However it only allows to a fix location because the fzf process will preserve the cwd and you can only move relative from the start. Maybe if fzf allows to change the cwd in a action that would be enough to keep moving up.

Never mind, I just realize that although that works to show other directories, it won't cd into them because it expects the same path from where it started. So yeah, it needs to be updated from the script that sets alt-c.

NOTE: Updated snipped. It should work as long as find return a relative path e.g. ../dir or an absolute path /home/user/foo

@LangLangBart
Copy link
Contributor

find .. -type d

Since version 0.47.01, fzf has started using a custom walker, and in subsequent iterations,
it has added some flags to it; it should be faster than find.

Reloading with a walker like this works, but there is an issue for adding a potential flag: #4062.

source <(fzf --zsh)
export FZF_ALT_C_OPTS="--bind 'ctrl-u:reload:</dev/tty FZF_DEFAULT_COMMAND= fzf --filter= --walker dir --walker-root ..'"

but I wanted to suggest making this a default binding since it would be really useful in a common
use case

The maintainer makes the call, but in the past, the saying went that the provided shell integration
are an offer to the user to use it and alter them to fit their needs.

Footnotes

  1. fzf/CHANGELOG.md 0.47.0

@junegunn
Copy link
Owner

junegunn commented Jan 28, 2025

Here's my take.

read -d '' FZF_ALT_C_OPTS << 'EOF'
  --bind 'ctrl-h:transform:
    dir="${FZF_PROMPT%%> }"
    dir="${dir:-.}"
    dir="$(realpath "$dir/..")"

    printf "top+change-prompt(%s> )" "$dir"
    printf "+reload:</dev/tty fzf --filter %q --walker dir --walker-root %s" "" "$dir"
  '
  --bind 'ctrl-l:transform:
    dir="${FZF_PROMPT%%> }"
    if [[ -n $dir ]]; then
      dir="$(realpath {})"
    else
      dir={}
    fi

    printf "top+change-prompt(%s> )" "$dir"
    printf "+reload:</dev/tty fzf --filter %q --walker dir --walker-root %s" "" "$dir"
  '
EOF
  • CTRL-H to go up to the parent, CTRL-L to go inside the directory
  • It uses the prompt as the placeholder for the current location

Since 80da077, this can be simplified as

read -d '' FZF_ALT_C_OPTS << 'EOF'
  --bind 'ctrl-h,ctrl-l:transform:
    dir="${FZF_PROMPT%%> }"
    if [[ $FZF_KEY = ctrl-h ]]; then
      dir="${dir:-.}"
      dir="$(realpath "$dir/..")"
    elif [[ -n $dir ]]; then
      dir="$(realpath {})"
    else
      dir={}
    fi

    printf "top+change-prompt(%s> )" "$dir"
    printf "+reload:</dev/tty fzf --filter %q --walker dir --walker-root %s" "" "$dir"
  '
EOF

While I like this, it's not easy to make it the default because we can't guarantee that it is compatible with the user's $FZF_ALT_C_OPTS and $FZF_ALT_C_COMMAND. Also, there's no universal consensus on which keys should be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants