junegunn / fzf

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

Bash history integration on Mac prefixing selected command with reverse index #3988

Open chuim opened 2 weeks ago

chuim commented 2 weeks ago

Checklist

Output of fzf --version

0.55.0 (brew)

OS

Shell

Problem / Steps to reproduce

After coming back from vacation and starting to use my company's MacBook, I noticed that the Bash history integration of FZF started doing this odd thing: when inserting a selected history item into the command line, it is now prefixed with the reverse index of that entry. It didn't use to do that a few weeks ago.

For instance, after pressing CTRL+R and selecting the highlighted item below:

$ `__fzf_history__`
  -10     cat .bashrc
  -9      ps -p $$
  -8      echo $SHELL
  -7      exit
  -6      -4 brew update && brew upgrade && brew cleanup
  -5      brew update && brew upgrade && brew cleanup
  -4      cat .profile
▌ -3      ll /opt/homebrew/opt/
  -2      vi .profile
  -1      history --help
  0       history | less
  379/379 +S ─────────────────────────────────────────────────────────
>

This is the command line that is inserted:

$ -3 ll /opt/homebrew/opt/

Whereas the correct/expected command should be:

$ ll /opt/homebrew/opt/
junegunn commented 2 weeks ago

No idea what's going on. Can you start bash like this,

bash --noprofile --rcfile <(fzf --bash) -x

press CTRL-R, and post the output?

chuim commented 1 week ago

I started bash that way but for some reason the FZF keyboard shortcuts were not working. So I dumped the contents of that same command into a file and sourced it, and that resolved it.

With this clean bash startup I am not getting the prefix issue anymore. A difference I noticed is that now the indexes presented in the selection list are positive, whereas, as I posted in the OP, when the problem happens they are presented as a negative count from the last history entry.

Looking at the diff between the commands shown by set -x when using the clean startup vs the default, I noticed a lot of stuff is being added in between each FZF command by my company's use of bash-preexec (the details of which I'm unsure if I can share here). The actual FZF commands being executed didn't change much but maybe those few differences are the root of the matter.

The commands executed when hitting CTRL+R with the clean bash are as follows:

bash-3.2$ `__fzf_history__`++ __fzf_history__
++ local output script
++ script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; s/\n/\n\t/gm; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
+++ set +o pipefail
+++ builtin fc -lnr -2147483648
++++ HISTTIMEFORMAT=
++++ builtin history 1
++++ __fzfcmd
++++ [[ -n '' ]]
++++ echo fzf
+++ last_hist='  501  source fzf_bash.sh '
+++ command perl -n -l0 -e 'BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; s/\n/\n\t/gm; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
+++ perl -n -l0 -e 'BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; s/\n/\n\t/gm; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
++++ __fzf_defaults '' '-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\''    ↳ '\'' --highlight-line  +m --read0'
++++ echo '--height 40% --bind=ctrl-z:ignore '
++++ command cat ''
++++ echo ' -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\''    ↳ '\'' --highlight-line  +m --read0'
+++ FZF_DEFAULT_OPTS='--height 40% --bind=ctrl-z:ignore
 -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\''   ↳ '\'' --highlight-line  +m --read0'
+++ FZF_DEFAULT_OPTS_FILE=
+++ fzf --query ''

There are 2 differences to he problematic execution.

`__fzf_history__`++

becomes

`__fzf_history__`+++ __bp_preexec_invoke_exec -x

and these two lines are not executed at all:

++++ [[ -n '' ]]
++++ echo fzf

My guess is that the latter bit is the problematic one.

It seems this is something specific to my environment, and I'll try to figure it out. Thanks for the help so far!