Skip to main content

Custom Headers and Contextual Actions

Multi-action Menu via --expect

--expect captures which key was pressed alongside the selection, allowing branching actions:

fzf file opener with multiple actions
fzf_open() {
local file
local key
local out

out=$(find . -type f | fzf \
--expect=ctrl-v,ctrl-x,ctrl-o,ctrl-d \
--header $'Enter: edit Ctrl+V: vsplit Ctrl+X: hsplit\nCtrl+O: xdg-open Ctrl+D: delete')

key=$(head -1 <<< "$out")
file=$(tail -1 <<< "$out")

[ -z "$file" ] && return

case "$key" in
ctrl-v) nvim -O "$file" ;; # vertical split
ctrl-x) nvim -o "$file" ;; # horizontal split
ctrl-o) xdg-open "$file" ;; # GUI open
ctrl-d)
echo "Delete $file? [y/N]"
read -r confirm
[[ "$confirm" == "y" ]] && rm "$file"
;;
*) nvim "$file" ;;
esac
}

Persistent Multi-action Loop

Stay in fzf, do multiple actions
fzf_manager() {
while true; do
local out key file

out=$(find . -type f \
| fzf \
--expect=ctrl-d,ctrl-r,ctrl-y,esc \
--preview 'bat --color=always {}' \
--preview-window 'right:50%' \
--header $'Enter: open Ctrl+D: delete Ctrl+R: rename\nCtrl+Y: copy path Esc: quit')

key=$(head -1 <<< "$out")
file=$(tail -1 <<< "$out")

case "$key" in
esc|"") break ;;
ctrl-d) rm -v "$file" ;;
ctrl-r)
read -rp "New name: " new_name
mv "$file" "$(dirname $file)/$new_name"
;;
ctrl-y)
echo -n "$file" | xclip -selection clipboard
echo "Copied: $file"
;;
*) nvim "$file" ;;
esac
done
}

Contextual Action Based on Filetype

fzf_smart_open() {
local file
file=$(find . -type f | fzf \
--preview '
ext="${1##*.}"
case "$ext" in
png|jpg|gif) chafa --size=60x30 {} ;;
pdf) pdftotext {} - | head -50 ;;
zip|tar*) unzip -l {} 2>/dev/null || tar -tvf {} ;;
*) bat --color=always --style=numbers {} ;;
esac
')

[ -z "$file" ] && return

case "${file##*.}" in
png|jpg|gif) xdg-open "$file" ;;
pdf) xdg-open "$file" ;;
md) nvim "$file" ;;
sh|bash) bash "$file" ;;
py) python "$file" ;;
*) nvim "$file" ;;
esac
}

What's Next