| name | fzf |
| description | Command-line fuzzy finder for interactive filtering of any list. Use when interactively selecting files, searching command history (CTRL-R), creating selection interfaces in scripts, building interactive menus, or integrating fuzzy search with tools like ripgrep, fd, and git. Triggers on mentions of fzf, fuzzy finder, ** completion, interactive filtering, or shell keybindings CTRL-T/CTRL-R/ALT-C. |
fzf - Command-Line Fuzzy Finder
Overview
fzf is a general-purpose command-line fuzzy finder. It reads a list of items from STDIN, allows interactive selection using fuzzy matching, and outputs the selected item(s) to STDOUT. Think of it as an interactive grep.
Key characteristics:
- Fast: Processes millions of items instantly
- Portable: Single binary, works everywhere
- Versatile: Customizable via event-action binding mechanism
- Integrated: Built-in shell integrations for bash, zsh, fish, and Nushell
When to Use This Skill
Use fzf when:
- Selecting files interactively:
vim $(fzf) or fuzzy completion with **<TAB>
- Searching command history: CTRL-R for fuzzy history search
- Navigating directories: ALT-C to cd into selected directory
- Building interactive scripts: Create selection menus for any list
- Filtering output: Pipe any command output through fzf
- Integrating with other tools: ripgrep, fd, git, etc.
Prerequisites
CRITICAL: Before proceeding, you MUST verify that fzf is installed:
fzf --version
Version note: This skill is documented against fzf 0.73.x. The fzf --bash/--zsh/--fish integration flags require fzf ≥0.48, --nushell requires ≥0.73, and --tmux/--popup are newer still. For the version that introduced any specific feature, see references/version-features.md.
If fzf is not installed:
- DO NOT attempt to install it automatically
- STOP and inform the user that fzf is required
- RECOMMEND manual installation with the following instructions:
brew install fzf
sudo apt install fzf
sudo pacman -S fzf
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
If fzf is not available, exit gracefully and do not proceed with the workflow below.
Shell Integration
fzf provides shell integration that enables powerful keybindings (CTRL-T, CTRL-R, ALT-C) and fuzzy completion (**<TAB>). These features require the user to configure their shell.
Note: Shell integration setup is the user's responsibility. If keybindings don't work, RECOMMEND the user add the appropriate line to their shell config:
eval "$(fzf --bash)"
source <(fzf --zsh)
fzf --fish | source
fzf --nushell | save -f ($nu.user-autoload-dirs | first | path join "_fzf_integration.nu")
The --bash/--zsh/--fish flags require fzf ≥0.48; --nushell requires fzf ≥0.73.
Key Bindings (requires shell integration)
| Key | Function | Description |
|---|
CTRL-T | File selection | Paste selected files/directories onto command line |
CTRL-R | History search | Fuzzy search command history |
ALT-C | Directory jump | cd into selected directory |
CTRL-R extras:
- Press
CTRL-R again to toggle sort by relevance
- Press
ALT-R to toggle between the cleaned and raw history line (toggle-raw, fzf 0.66+)
- Press
CTRL-/ or ALT-/ to toggle line wrapping
Fuzzy Completion (**<TAB>)
Trigger fuzzy completion with ** followed by TAB:
vim **<TAB>
vim ../fzf**<TAB>
cd **<TAB>
kill -9 **<TAB>
ssh **<TAB>
export **<TAB>
Search Syntax
fzf uses extended-search mode by default. Multiple search terms are separated by spaces.
| Token | Match Type | Description |
|---|
sbtrkt | Fuzzy match | Items matching sbtrkt |
'wild | Exact match | Items containing wild exactly |
'wild' | Exact boundary | Items with wild at word boundaries (fzf 0.55+) |
^music | Prefix match | Items starting with music |
.mp3$ | Suffix match | Items ending with .mp3 |
!fire | Inverse match | Items NOT containing fire |
!^music | Inverse prefix | Items NOT starting with music |
!.mp3$ | Inverse suffix | Items NOT ending with .mp3 |
Exact mode: Start fzf with -e/--exact to make bare terms exact-match
instead of fuzzy (no need to quote every word). Note that when --exact is
set, the '-prefix "unquotes" the term — 'sbtrkt becomes a fuzzy match.
OR operator: Use | to match any of several patterns:
^core go$ | rb$ | py$
Escape spaces: Use \ to match literal space characters.
Basic Usage
Simple Selection
vim $(fzf)
fzf --print0 | xargs -0 -o vim
fzf --bind 'enter:become(vim {})'
Multi-Select
fzf -m
Preview Window
fzf --preview 'cat {}'
fzf --preview 'bat --color=always {}'
fzf --preview 'cat {}' --preview-window=right,50%
fzf --preview 'cat {}' --preview-window=up,40%,border-bottom
Display Modes
Height Mode
fzf --height 40%
seq 5 | fzf --height ~100%
fzf --height 40% --layout reverse --border
tmux Mode (fzf 0.53+)
fzf --tmux center
fzf --tmux 80%
fzf --tmux left,40%
fzf --tmux bottom,30%
In fzf 0.71+, --popup is the newer name (it also targets Zellij floating panes); --tmux still works as an alias.
Essential Options
Layout and Appearance
--height=HEIGHT[%]
--layout=reverse
--border[=STYLE]
--margin=MARGIN
--padding=PADDING
--info=STYLE
Search Behavior
-e, --exact
-i
+i
--scheme=SCHEME
--algo=TYPE
Input/Output
-m, --multi
--read0
--print0
--ansi
Field Processing
--delimiter=STR
--nth=N[,..]
--with-nth=N[,..]
Event Bindings
Customize behavior with --bind:
fzf --bind 'KEY:ACTION'
fzf --bind 'EVENT:ACTION'
fzf --bind 'KEY:ACTION1+ACTION2'
fzf --bind 'ctrl-a:select-all'
fzf --bind 'ctrl-d:deselect-all'
fzf --bind 'ctrl-/:toggle-preview'
fzf --bind 'enter:become(vim {})'
Key Actions (Selection)
| Action | Description |
|---|
accept | Accept current selection |
abort | Abort and exit |
toggle | Toggle selection of current item |
select-all | Select all matches |
deselect-all | Deselect all |
toggle-all | Toggle all selections |
Useful Actions
| Action | Description |
|---|
reload(cmd) | Reload list from command |
become(cmd) | Replace fzf with command (fzf 0.38+) |
execute(cmd) | Run command, return to fzf |
execute-silent(cmd) | Run command silently |
preview(cmd) | Change preview command |
toggle-preview | Show/hide preview |
change-prompt(str) | Change prompt string |
Events
| Event | Triggered When |
|---|
start | fzf starts |
load | Input loading completes |
change | Query string changes |
focus | Focused item changes |
result | Result list updates |
For complete action reference, see references/actions.md.
Environment Variables
Core Configuration
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_DEFAULT_OPTS='--height 40% --layout reverse --border'
export FZF_DEFAULT_OPTS_FILE=~/.fzfrc
Shell Integration Variables
export FZF_CTRL_T_COMMAND="fd --type f"
export FZF_CTRL_T_OPTS="--preview 'bat --color=always {}'"
export FZF_CTRL_R_OPTS="--bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'"
export FZF_ALT_C_COMMAND="fd --type d"
export FZF_ALT_C_OPTS="--preview 'tree -C {}'"
Completion Customization
export FZF_COMPLETION_TRIGGER='~~'
export FZF_COMPLETION_OPTS='--border --info=inline'
Common Patterns
Find and Edit Files
fd --type f | fzf --preview 'bat --color=always {}' | xargs -o vim
fd --type f | fzf --preview 'bat --color=always {}' --bind 'enter:become(vim {})'
Search File Contents (with ripgrep)
rg --line-number . | fzf --delimiter : --preview 'bat --color=always {1} --highlight-line {2}'
rg --line-number . | fzf --delimiter : --bind 'enter:become(vim {1} +{2})'
Git Integration
git branch | fzf | xargs git checkout
git log --oneline | fzf --preview 'git show {1}' | cut -d' ' -f1
git status -s | fzf -m | awk '{print $2}' | xargs git add
Dynamic List Reloading
ps -ef | fzf --bind 'ctrl-r:reload(ps -ef)' --header 'Press CTRL-R to reload'
fd | fzf --bind 'ctrl-d:reload(fd --type d)' --bind 'ctrl-f:reload(fd --type f)'
Interactive ripgrep Launcher
RG_PREFIX="rg --column --line-number --no-heading --color=always"
fzf --ansi --disabled \
--bind "start:reload:$RG_PREFIX ''" \
--bind "change:reload:$RG_PREFIX {q} || true" \
--bind 'enter:become(vim {1} +{2})' \
--delimiter :
Placeholders
Use in --preview, --bind, etc.:
| Placeholder | Description |
|---|
{} | Current selection (quoted) |
{+} | All selected items (space-separated) |
{q} | Current query string |
{n} | Zero-based index of current item |
{1}, {2}, etc. | Nth field (with --delimiter) |
{-1} | Last field |
{1..3} | Fields 1 through 3 |
{2..} | Fields 2 to end |
Flags:
{+} - All selected items
{f} - Write to temp file (for large lists)
{r} - Raw (unquoted) output
Advanced Topics
For detailed documentation on advanced features, see:
Troubleshooting
"Command not found: fzf"
- fzf is not installed. See Prerequisites section for manual installation instructions
- Do NOT attempt automatic installation
Shell keybindings not working (CTRL-T, CTRL-R, ALT-C):
- Shell integration must be configured by the user
- RECOMMEND adding the appropriate line to shell config (see Shell Integration section)
- For bash, must be sourced after any PS1 modifications
Performance issues:
- Avoid
--ansi in FZF_DEFAULT_OPTS (slows initial scan)
- Use
--nth sparingly (requires tokenization)
- Prefer string
--delimiter over regex
Preview not showing:
- Check preview command syntax
- Use
{} placeholder for current selection
- Test preview command manually first
CTRL-R not finding old commands:
- fzf searches shell history, not history file
- Increase
HISTSIZE and HISTFILESIZE
Resources