Not working with fzf-history-widget when pressing ctrl+r
zellij --version: 0.41.1
Terminal version: wezterm 20240203-110809-5046fc22
Operating system: OS X
Issue description
It works well with fzf except with the keybinding CTRL+R to see the history
Minimal reproduction
brew install fzf
Add source <(fzf --zsh) to .zshrc
source ~/.zshrc
Then press Ctrl+R and zellij autolock doesn't work
Other relevant information
After spending several hours troubleshooting and with the help of ChatGPT, I discovered that the issue was caused by the fzf-history-widget using a subshell.
To address this, I modified the widget to avoid using a subshell for storing the selected value. Instead, I ensured that fzf runs as a foreground process rather than in the background. Here's the updated code in case it helps someone else:
I edited the widget code in /opt/homebrew/opt/fzf/shell/key-bindings.zsh to use read -r selected instead of a subshell:
Please let me know if there is a better way to fix it, I don't have experience with bash scripting.
fzf-history-widget() {
local selected
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases noglob nobash_rematch 2> /dev/null
# Ensure the associative history array is loaded, and Perl is installed for multi-line support.
if zmodload -F zsh/parameter p:history 2>/dev/null && (( ${#commands[perl]} )); then
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) | read -r selected
else
# Use a temporary file to capture fzf output
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='' fzf | read -r selected
fi
# Handle the result
local ret=$?
if [ -n "$selected" ]; then
if [[ $(awk '{print $1; exit}' <<< "$selected") =~ ^[1-9][0-9]*$ ]]; then
zle vi-fetch-history -n $MATCH
else
LBUFFER="$selected"
fi
fi
zle reset-prompt
return $ret
}
Another way to resolve this issue is by adding support for handling subshell processes to the plugin.
Thanks for sharing your solution. I use atuin, so I've never encountered this.
This plugin can only evaluate what is returned by Zellij, which is N/A in this case.
Using the Ctrl r mapping below, you can disable the autolock mechanism and immediately enter locked mode. But this requires explicitly re-enabling the autolock after you've made your selection (not cool).
normal {
bind "Ctrl r" {
WriteChars "\u{0012}"; // Passthru `Ctrl+r`
MessagePlugin "autolock" {payload "disable";};// Disable the autolock plugin.
SwitchToMode "Locked";
}
}
Note that it's also possible to toggle the plugin from the shell:
zellij pipe --name autolock -- [enable|disable|toggle]
and toggle the lock status using:
zellij action switch-mode [locked|normal]
I tried to figure out another approach, but gave up. Thanks for sharing.