junegunn / fzf

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

0.53.0: --bind behaviour changed? #3865

Closed 097115 closed 2 weeks ago

097115 commented 2 weeks ago

Checklist

Output of fzf --version

0.53.0 (c4a9ccd)

OS

Shell

Problem / Steps to reproduce

Consider this:

q=''
q=$(printf "aaa\nbbb\nccc\n" | fzf --bind='f1:execute(printf bbb)+abort' --bind='f2:execute(printf ccc)+accept')
printf "\n$q\n"

Prior to 0.53.0, pressing F1 would result in setting $q to bbb, while pressing F2 would result in setting it to cccaaa

Now, with 0.53.0, pressing F1 results in printing bbb to stdout and leaving $q unset, while pressing F2 results in printing ccc to stdout and setting $q to aaa.

So, my question, probably, is if the changes were intentional, and if so, then how can I now replicate the prior-0.53.0 behaviour?

Thanks :)

junegunn commented 2 weeks ago

Yes, it is intentional. execute action is for executing an external program in the alternate screen without leaving fzf, and it isn't supposed to affect the final output of fzf.

https://github.com/junegunn/fzf/blob/6de0a7ddc11dd9d4a2261e9642a99f3901e0ae27/CHANGELOG.md?plain=1#L71-L75

For example, when you run selected=$(ls | fzf --bind 'ctrl-o:execute:vim {}'), you don't want any output from Vim in the final output of fzf. Also, prior to 0.53.0, you would have to redirect the standard output of Vim to /dev/tty for it to work properly in this case. Considering the original purpose of execute, this was confusing and not ergonomic.

Another mistake here is using execute where you should be using execute-silent. execute runs the command in the alternate screen, you'll notice screen flashing.

fzf --bind 'space:execute-silent(ls)+accept' --height 30%

how can I now replicate the prior-0.53.0 behaviour?

1. Use print action

fzf --bind 'f1:print(f1)+accept' fzf --bind 'f2:print(f2)+abort'

2. Use become action

fzf --bind 'f1:become:echo f1; echo {}' --bind 'f2:become:echo f2; exit 1'

3. Use --expect

If you just need the key names to be printed, --expect is the simplest.

fzf --expect f1,f2
097115 commented 2 weeks ago

So, for the reference, it's

--bind 'f2:print(ccc)+accept'

instead of

--bind='f2:execute(printf ccc)+accept'

to get ccc aaa from the example above. And (with optional exit 1 if needed)

--bind 'f1:become:echo bbb' 

instead of

--bind='f1:execute(printf bbb)+abort'

to get bbb.

While certainly looking more logical and more consistent, it's quite a breaking change, I'd say...

097115 commented 2 weeks ago

Forgot to say thanks for the explanation :)

junegunn commented 2 weeks ago

it's quite a breaking change

Yeah, but I'd say it was a misuse of a feature, like the spacebar heating case.