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

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

Open
5 of 10 tasks
chuim opened this issue Sep 6, 2024 · 3 comments
Open
5 of 10 tasks

Comments

@chuim
Copy link

chuim commented Sep 6, 2024

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.55.0 (brew)

OS

  • Linux
  • macOS
  • Windows
  • Etc.

Shell

  • bash
  • zsh
  • fish

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
Copy link
Owner

junegunn commented Sep 7, 2024

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
Copy link
Author

chuim commented Sep 9, 2024

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!

@mrahtz
Copy link

mrahtz commented Nov 10, 2024

For any other Google folks that land here with the same issue on their corp machines: I've narrowed it down to this line in key-bindings.bash:

last_hist=$(HISTTIMEFORMAT='' builtin history 1) command perl -n -l0 -e "$script" |

When I run with my default shell setup, last_hist ends up empty. For example, if I change the Perl script in $script to have:

print "last_hist: |" . $ENV{last_hist} . "|; HISTCOUNT: |" . $HISTCOUNT . "|; \$.: |" . $. . "|"'

Then the output I see when running __fzf_history__ is:

...
last_hist: ||; HISTCOUNT: |1|; $.: |2|
last_hist: ||; HISTCOUNT: |1|; $.: |1|

Whereas when I run it in a shell started with bash --norc, then last_hist is not empty:

...
last_hist: |  501  <some command> |; HISTCOUNT: |502|; $.: |2|
last_hist: |  501  <some command> |; HISTCOUNT: |502|; $.: |1|

I suspect as @chuim says it's something to do with the bash-preexec setup we use, but I didn't get fully to the bottom of it. For now I've settled on a workaround of forcing the awk version instead of the Perl version by changing perl to perlfoo on this line:

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

Thanks!

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

No branches or pull requests

3 participants