Skip to main content

Advanced Preview Techniques

Advanced preview patterns turn fzf from a simple picker into a rich, context-sensitive browser.

Dynamic Preview — Change Based on Focused Item

# Show different preview based on whether item is file or directory
find . | fzf \
--preview '
if [ -d {} ]; then
tree -C -L 2 {}
elif [ -f {} ]; then
bat --color=always --style=numbers --line-range=:200 {}
else
echo "Not a file or directory"
fi
'

change-preview Binding — Switch Preview Mode

ls | fzf \
--preview 'bat --color=always {}' \
--bind 'ctrl-p:change-preview(cat -n {})' \
--bind 'ctrl-b:change-preview(bat --color=always {})' \
--bind 'ctrl-t:change-preview(file {})' \
--header 'Ctrl+P: raw Ctrl+B: bat Ctrl+T: file info'

Git-aware Preview

Git Log with Delta

# Show git log with syntax-highlighted diff
git log --oneline | fzf \
--preview 'git show --stat --color=always {1}' \
--bind 'ctrl-d:change-preview(git diff --color=always {1})' \
--bind 'ctrl-s:change-preview(git show --color=always {1})' \
--header 'Ctrl+D: diff Ctrl+S: show'

Git Status with Preview

git status --short | fzf \
--preview '
file=$(echo {} | awk "{print \$2}")
if git diff --cached -- "$file" | grep -q .; then
git diff --cached --color=always -- "$file"
else
git diff --color=always -- "$file"
fi
'

Preview with delta (Beautiful Diffs)

# delta for syntax-highlighted, side-by-side diffs
git log --oneline | fzf \
--preview 'git show {1} | delta --paging=never --width=$FZF_PREVIEW_COLUMNS'

Scrolling to Matching Line in Grep Output

# Live grep with file preview scrolled to match
rg --line-number --no-heading --color=always "" | fzf \
--ansi \
--delimiter=: \
--preview 'bat --color=always --style=numbers --highlight-line={2} {1}' \
--preview-window 'right:60%:+{2}/2'

The +{2}/2 tells fzf to:

  • Scroll to line {2} in the preview
  • Center it (divide by 2)

--with-nth for Formatted Display + Full Preview

# Show truncated display but preview uses full path
find . -type f | fzf \
--with-nth=1 \
--delimiter='/' \
--preview 'bat --color=always {}'
# Searches only by filename (last component), but preview shows full file

Image Preview with kitty or chafa

If your terminal supports images (Kitty, iTerm2, Sixel):

# With chafa (universal, works in most terminals)
find . -name "*.png" -o -name "*.jpg" -o -name "*.gif" | fzf \
--preview 'chafa --size=60x30 {}' \
--preview-window 'right:60%'

# With kitty icat
find . -name "*.png" | fzf \
--preview 'kitty icat --clear --transfer-mode=memory --stdin=no --place="${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0" {}'

Preview Environment Variables

Inside the preview command, fzf exposes:

VariableValue
FZF_PREVIEW_COLUMNSWidth of preview window in columns
FZF_PREVIEW_LINESHeight of preview window in lines
FZF_PREVIEW_LEFTLeft position
FZF_PREVIEW_TOPTop position
# Use window dimensions for responsive preview
ls | fzf --preview '
if [ $FZF_PREVIEW_COLUMNS -gt 80 ]; then
bat --color=always --style=numbers --line-range=:200 {}
else
head -20 {}
fi
'

Combining Preview with Multi-select

# Preview the last selected file; select multiple to open all
find . -type f | fzf \
-m \
--preview 'bat --color=always {}' \
--preview-window='right:50%' \
--bind 'ctrl-/:toggle-preview' \
--header 'Tab: mark Enter: open all selected'

What's Next