Skip to content
Back to skills

Fzf

BSecurity

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.

  • 666 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added February 8, 2026
toolsgoshellbashgitfrontendperformancedocumentation

Works with

  • terminal

Security analysis

B75/100
  • criticalModifies startup scripts or system services for persistence
  • criticalModifies startup scripts or system services for persistence

Pro shows the line behind each finding and how to fix it

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill fzf --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fzf?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fzf
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-fzf/badge)](https://www.skillsdirectory.com/skills/majiayu000-fzf)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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, and fish

## 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:

```bash
fzf --version
```

**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:

```bash
# macOS
brew install fzf

# Debian/Ubuntu
sudo apt install fzf

# Arch Linux
sudo pacman -S fzf

# From source
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

# Other systems: see https://github.com/junegunn/fzf#installation
```

**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:

```bash
# Bash (~/.bashrc)
eval "$(fzf --bash)"

# Zsh (~/.zshrc)
source <(fzf --zsh)

# Fish (~/.config/fish/config.fish)
fzf --fish | source
```

### 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 raw mode (see surrounding items)
- Press `CTRL-/` or `ALT-/` to toggle line wrapping

### Fuzzy Completion (`**<TAB>`)

Trigger fuzzy completion with `**` followed by TAB:

```bash
# Files under current directory
vim **<TAB>

# Files under specific directory
vim ../fzf**<TAB>

# Directories only
cd **<TAB>

# Process IDs (for kill)
kill -9 **<TAB>

# SSH hostnames
ssh **<TAB>

# Environment variables
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 |
| `^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` |

**OR operator**: Use `|` to match any of several patterns:
```bash
# Files starting with 'core' and ending with go, rb, or py
^core go$ | rb$ | py$
```

**Escape spaces**: Use `\ ` to match literal space characters.

## Basic Usage

### Simple Selection

```bash
# Select a file and open in vim
vim $(fzf)

# Safer with xargs (handles spaces, cancellation)
fzf --print0 | xargs -0 -o vim

# Using become() action (best approach)
fzf --bind 'enter:become(vim {})'
```

### Multi-Select

```bash
# Enable multi-select with -m
fzf -m

# Select with TAB, deselect with Shift-TAB
# Selected items printed on separate lines
```

### Preview Window

```bash
# Basic preview
fzf --preview 'cat {}'

# With syntax highlighting (requires bat)
fzf --preview 'bat --color=always {}'

# Customize preview window position/size
fzf --preview 'cat {}' --preview-window=right,50%
fzf --preview 'cat {}' --preview-window=up,40%,border-bottom
```

## Display Modes

### Height Mode

```bash
# Use 40% of terminal height
fzf --height 40%

# Adaptive height (shrinks for small lists)
seq 5 | fzf --height ~100%

# With layout options
fzf --height 40% --layout reverse --border
```

### tmux Mode

```bash
# Open in tmux popup (requires tmux 3.3+)
fzf --tmux center         # Center, 50% width/height
fzf --tmux 80%            # Center, 80% width/height
fzf --tmux left,40%       # Left side, 40% width
fzf --tmux bottom,30%     # Bottom, 30% height
```

## Essential Options

### Layout and Appearance

```bash
--height=HEIGHT[%]     # Non-fullscreen mode
--layout=reverse       # Display from top (default: bottom)
--border[=STYLE]       # rounded, sharp, bold, double, block
--margin=MARGIN        # Margin around finder
--padding=PADDING      # Padding inside border
--info=STYLE           # default, inline, hidden
```

### Search Behavior

```bash
-e, --exact            # Exact match (disable fuzzy)
-i                     # Case-insensitive
+i                     # Case-sensitive
--scheme=SCHEME        # default, path, history
--algo=TYPE            # v2 (quality), v1 (performance)
```

### Input/Output

```bash
-m, --multi            # Enable multi-select
--read0                # Read NUL-delimited input
--print0               # Print NUL-delimited output
--ansi                 # Enable ANSI color processing
```

### Field Processing

```bash
--delimiter=STR        # Field delimiter (default: AWK-style)
--nth=N[,..]           # Limit search to specific fields
--with-nth=N[,..]      # Transform display of each line
```

## Event Bindings

Customize behavior with `--bind`:

```bash
# Basic syntax
fzf --bind 'KEY:ACTION'
fzf --bind 'EVENT:ACTION'
fzf --bind 'KEY:ACTION1+ACTION2'  # Chain actions

# Examples
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 |
| `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](references/actions.md).

## Environment Variables

### Core Configuration

```bash
# Default command when input is TTY
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'

# Default options (applied to all fzf invocations)
export FZF_DEFAULT_OPTS='--height 40% --layout reverse --border'

# Options file (alternative to FZF_DEFAULT_OPTS)
export FZF_DEFAULT_OPTS_FILE=~/.fzfrc
```

### Shell Integration Variables

```bash
# CTRL-T options
export FZF_CTRL_T_COMMAND="fd --type f"
export FZF_CTRL_T_OPTS="--preview 'bat --color=always {}'"

# CTRL-R options
export FZF_CTRL_R_OPTS="--bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'"

# ALT-C options
export FZF_ALT_C_COMMAND="fd --type d"
export FZF_ALT_C_OPTS="--preview 'tree -C {}'"
```

### Completion Customization

```bash
# Change trigger sequence (default: **)
export FZF_COMPLETION_TRIGGER='~~'

# Completion options
export FZF_COMPLETION_OPTS='--border --info=inline'
```

## Common Patterns

### Find and Edit Files

```bash
# Using fd for better performance
fd --type f | fzf --preview 'bat --color=always {}' | xargs -o vim

# Or with become()
fd --type f | fzf --preview 'bat --color=always {}' --bind 'enter:become(vim {})'
```

### Search File Contents (with ripgrep)

```bash
# Basic ripgrep integration
rg --line-number . | fzf --delimiter : --preview 'bat --color=always {1} --highlight-line {2}'

# Open result in vim at line
rg --line-number . | fzf --delimiter : --bind 'enter:become(vim {1} +{2})'
```

### Git Integration

```bash
# Select git branch
git branch | fzf | xargs git checkout

# Select commit
git log --oneline | fzf --preview 'git show {1}' | cut -d' ' -f1

# Stage files interactively
git status -s | fzf -m | awk '{print $2}' | xargs git add
```

### Dynamic List Reloading

```bash
# Reload process list with CTRL-R
ps -ef | fzf --bind 'ctrl-r:reload(ps -ef)' --header 'Press CTRL-R to reload'

# Toggle between files and directories
fd | fzf --bind 'ctrl-d:reload(fd --type d)' --bind 'ctrl-f:reload(fd --type f)'
```

### Interactive ripgrep Launcher

```bash
# fzf as ripgrep frontend (search updates on typing)
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:

- [references/actions.md](references/actions.md) - Complete list of bindable actions
- [references/options.md](references/options.md) - Full options reference
- [references/integrations.md](references/integrations.md) - ripgrep, fd, git, bat integrations

## 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

- **Man page**: `man fzf` or `fzf --man`
- **Wiki examples**: https://github.com/junegunn/fzf/wiki/examples
- **Advanced examples**: https://github.com/junegunn/fzf/blob/master/ADVANCED.md
- **Theme playground**: https://vitormv.github.io/fzf-themes/
- **fzf-git.sh**: https://github.com/junegunn/fzf-git.sh (git keybindings)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.