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

0.56.1 broke fzf-history-widget completion in zsh 5.9 when share_history is enabled #4091

Closed
5 of 10 tasks
jnd-au opened this issue Nov 12, 2024 · 8 comments · Fixed by #4093
Closed
5 of 10 tasks

0.56.1 broke fzf-history-widget completion in zsh 5.9 when share_history is enabled #4091

jnd-au opened this issue Nov 12, 2024 · 8 comments · Fixed by #4093

Comments

@jnd-au
Copy link

jnd-au commented Nov 12, 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.56.2 (brew)

OS

  • Linux
  • macOS
  • Windows
  • Etc.

Shell

  • bash
  • zsh
  • fish

Problem / Steps to reproduce

This seems related to #4061:

I am using default source <(fzf --zsh) from macOS Homebrew with zsh 5.9 (x86_64-apple-darwin23.0) with setopt share_history enabled, but as of fzf version 0.56.1 the history completion with ^R bound to fzf-history-widget is broken (last working version was 0.56.0). Previous behaviour in zsh was that foo^r^m would return fzf’s default matching result for foo (e.g. found-history) but now it returns my original input string foo. In the simplest case of ^r^m the widget simply returns nothing (previously, it would have returned the fzf’s default selected item). Intermittently it does return a result, but rarely. Despite having share_history enabled, I do not have a second shell using the history file; this issue is reproducible with a single shell on its own. (And unlike #4088 I’m not using FZF_COMPLETION_TRIGGER.) If I downgrade to 0.56.0 or disable share_history the previous expected behaviour is restored.

@LangLangBart
Copy link
Contributor

0.56.2 (brew)

but as of fzf version 0.56.1 the history completion

Just to confirm, you also tested 0.56.2 and the issue remains?

Please share your options.

unsetopt KSH_OPTION_PRINT
print -r -- $(setopt)

Could you give me some guidance on the individual steps I need to take to see the issue?

A minimal zsh version with a couple of steps ...

command env -i HOME=$HOME TERM=$TERM USER=$USER PATH=$PATH zsh -f -o sharehistory
source <(fzf --zsh)
# press 'Control-R'
# ?

@ryanwi
Copy link

ryanwi commented Nov 13, 2024

I am experiencing this issue too.

  • Latest iTerm, MacOS, fzf.
  • Using Zsh.
% fzf --version
0.56.2 (brew)

% unsetopt KSH_OPTION_PRINT
% print -r -- $(setopt)
combiningchars extendedhistory histignorealldups histreduceblanks interactive login promptsubst sharehistory shinstdin

in .zshrc

# history
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt EXTENDED_HISTORY          # write the history file in the ":start:elapsed;command" format.
setopt HIST_REDUCE_BLANKS        # remove superfluous blanks before recording entry.
setopt SHARE_HISTORY             # share history between all sessions.
setopt HIST_IGNORE_ALL_DUPS      # delete old recorded entry if new entry is a duplicate.

source <(fzf --zsh)
  1. press 'Control-R' - history appears and searches great
  2. After selecting the desired history command, fzf closes and nothing is written to the prompt

After commenting out the setopt SHARE_HISTORY option, fzf works again.

@LangLangBart
Copy link
Contributor

LangLangBart commented Nov 13, 2024

@ryanwi, does the issue disappear if you do the following:

  1. Press ⏎ Enter before opening the fzf-history.
  2. Open the fzf-history-widget with your assigned key (default ⌃ Control + R).
  3. Make your selection. Was the desired item successfully retrieved?

In the meantime, this workaround will remove the fc -RI call, which likely
causes the mischief, but you'll still encounter the original issue1 it was
intended to solve.

source <(fzf --zsh | sed 's/fc -RI/true/')

Footnotes

  1. ctrl+r no longer pulling from shared history until a command is run succesfully · Issue #4061 · junegunn/fzf · GitHub

@jnd-au
Copy link
Author

jnd-au commented Nov 13, 2024

Thanks very much @LangLangBart and @ryanwi. For me: pressing ⏎ Enter doesn’t help, but removing fc -RI does! Without fc -RI the history and indexes shown in fzf are correct (matching the shell session), but with fc -RI the history list and indexes shown in fzf are wildly wrong when HISTFILE is non-empty.

@LangLangBart
Copy link
Contributor

LangLangBart commented Nov 13, 2024

Thanks for the confirmation, could you test an earlier version of the
keybinding1, before the fc -RI call was moved inside the command
substitution $(…)?

fzf/shell/key-bindings.zsh

Lines 116 to 118 in d938fdc

# 'history' array only updates after executing a non-empty command.
[[ "${options[sharehistory]}" == "on" ]] && fc -RI
selected="$(printf '%s\t%s\000' "${(kv)history[@]}" |

Just run:

source <(curl -fsSL https://raw.githubusercontent.com/junegunn/fzf/d938fdc/shell/key-bindings.zsh) 

Footnotes

  1. fix(zsh): history loading with shared option by LangLangBart · Pull Request #4071 · junegunn/fzf · GitHub

@jnd-au
Copy link
Author

jnd-au commented Nov 13, 2024

Yes, d938fdc “works” (selected item appears on the zsh line) but has the problematic side-effect of heavily mutating the shell history every time fzf is used: changes the order and numbers of items in the history, and up-arrow takes me to the wrong (out of order) history lines.

@LangLangBart
Copy link
Contributor

Thanks again for testing. I might propose reverting fc -RI and reopening #4061.

We could move sharehistory into the if… block so that fc -… with awk
handles the history. However, this isn't a good solution, as some users would be
confused about why they need to disable sharehistory to see multiline fzf
history, right?

fzf/shell/key-bindings.zsh

Lines 113 to 130 in 215ab48

# lines, are set. Also, make sure Perl is installed for multi-line output.
if zmodload -F zsh/parameter p:{commands,history} 2>/dev/null && (( ${+commands[perl]} )); then
# Import commands from other shells if SHARE_HISTORY is enabled, as the
# 'history' array only updates after executing a non-empty command.
selected="$(
if [[ -o sharehistory ]]; then
fc -RI
fi
printf '%s\t%s\000' "${(kv)history[@]}" |
perl -0 -ne 'if (!$seen{(/^\s*[0-9]+\**\t(.*)/s, $1)}++) { s/\n/\n\t/g; print; }' |
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --read0") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
else
selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
fi
local ret=$?

@jnd-au
Copy link
Author

jnd-au commented Nov 13, 2024

Hmm yeah, revert and re-open seems fair, given that it minimises the unresolved corner case and retains the overall functionality until a cleaner solution is found.

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

Successfully merging a pull request may close this issue.

3 participants