THE QUESTION
I've been trying to use fzf to bind a shortcut (preferebly Ctrl + o) to interactively search a file and pipe it to xdg-open
in zsh. Many shortcuts are already part of the fzf
utility, as long as you source the file located in fzf/shell/key-bindings.zsh. There, you'll find snippets for binding Ctrl + r to fuzzy search your command history and Ctrl + t to fuzzy complete your current command line. Here's what the first shortcut looks like in fzf's source code:
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
selected=( $(fc -rl 1 | perl -ne 'print if !$seen{(/^\s*[0-9]+\**\s+(.*)/, $1)}++' |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
local ret=$?
if [ -n "$selected" ]; then
num=$selected[1]
if [ -n "$num" ]; then
zle vi-fetch-history -n $num
fi
fi
zle reset-prompt
return $ret
}
zle -N fzf-history-widget
bindkey '^R' fzf-history-widget
Of course, its behavior is a bit different from the behavior I want since it pastes the selected result to the command line instead of piping it directly to a command. The following bash script, though, has precisely the behavior I expected and running it does a much better job at explaining it than myself.
bind -x '"\C-o": file="$(fzf --height 40% --reverse)" && [ -f "$file" ] && xdg-open "$file"'
I've also found this fish function with the same behavior, but fish's syntax is very different from POSIX compliant shells like zsh and bash so I don't know how helpful of reference that can be.
Now then, does anyone know to bind Ctrl + o to an interactive fzf search that pipes its result directly to xdg-open
in zsh?
Thanks in advance!
THE ANSWER
Here's a working script, which I wrote based on this Stack Overflow answer.
fuzzy-xdg-open() {
local output
output=$(fzf --height 40% --reverse </dev/tty) && xdg-open ${(q-)output}
zle reset-prompt
}
zle -N fuzzy-xdg-open
bindkey '^o' fuzzy-xdg-open
bind
? Or do you have another issue? The current question is extremely narrow and doesn't clearly state what the end goal is.