Skip to main content

Bash and Zsh Shell Integration

fzf ships with powerful built-in shell integrations that replace three of the most-used interactive shell features: file completion, history search, and directory jumping.

Enabling the Integration

Bash

~/.bashrc
# Modern fzf (0.48+) — single command
eval "$(fzf --bash)"

# Older fzf — source individual files
source ~/.fzf.bash

Zsh

~/.zshrc
# Modern fzf (0.48+)
eval "$(fzf --zsh)"

# Older fzf
source ~/.fzf.zsh

After adding to your config: source ~/.bashrc or source ~/.zshrc.

The Three Built-in Key Bindings

CTRL-T — File Finder (Paste Path to Command Line)

Press CTRL-T at any point in your command line to interactively search for files. The selected path is pasted at the cursor position:

# Scenario: you want to run:  nvim /some/path/to/file.lua
# What you type:
nvim [CTRL-T]
# fzf opens → you find the file → path is inserted:
nvim /opt/docker-data/apps/docusaurus/site/docs/server/cli/fzf/index.mdx

Customizing CTRL-T

~/.bashrc or ~/.zshrc
# Change the source command (default: find . -type f)
export FZF_CTRL_T_COMMAND="fd --type f --hidden --follow --exclude .git"

# Add preview for CTRL-T
export FZF_CTRL_T_OPTS="
--preview 'bat --color=always --style=numbers --line-range=:200 {}'
--preview-window 'right:60%:hidden'
--bind 'ctrl-/:toggle-preview'
--bind 'ctrl-u:preview-half-page-up'
--bind 'ctrl-d:preview-half-page-down'
"

Press CTRL-R to search your shell history interactively. Replaces the default history reverse-search with a fuzzy, full-history browser:

# Default CTRL-R shows last 20 items
# fzf CTRL-R shows your ENTIRE history, fuzzy-searchable
[CTRL-R]
# Type: "docker run" to find previous docker run commands
# Type: "git rebase" to find your rebase patterns

Customizing CTRL-R

~/.bashrc or ~/.zshrc
export FZF_CTRL_R_OPTS="
--scheme=history
--preview 'echo {}'
--preview-window 'up:3:hidden:wrap'
--bind 'ctrl-/:toggle-preview'
--bind 'ctrl-y:execute-silent(echo -n {2..} | xclip -selection clipboard)+abort'
--color header:italic
--header 'CTRL-Y: copy command to clipboard'
"

ALT-C — Directory Jump

Press ALT-C to interactively search directories and cd into the selected one:

# Scenario: you want to cd into a project directory
[ALT-C]
# Type: "docusaurus" → fzf shows matching directories → Enter to cd
# Shell executes: cd /opt/docker-data/apps/docusaurus

Customizing ALT-C

~/.bashrc or ~/.zshrc
# Change source (default: find . -type d)
export FZF_ALT_C_COMMAND="fd --type d --hidden --follow --exclude .git"

# Add tree preview for directories
export FZF_ALT_C_OPTS="
--preview 'tree -C {} | head -200'
--preview-window 'right:50%'
"

Shell Completion (Fuzzy Completion with **)

fzf replaces tab-completion for several commands using the ** trigger:

# Fuzzy file completion
vim **<Tab> # opens fzf to pick a file for vim
cat **<Tab>
cp src/**<Tab> dest/

# Directory completion
cd **<Tab>
ls **<Tab>

# Process ID completion (for kill and similar)
kill -9 **<Tab>

# Host completion (SSH, ping, etc.)
ssh **<Tab> # reads from ~/.ssh/known_hosts + ~/.ssh/config

# Environment variable completion
unset **<Tab>
export **<Tab>

Adding Fuzzy Completion to Custom Commands

~/.bashrc
# complete 'mything' with file list fuzzy
_fzf_complete_mything() {
_fzf_complete --multi --prompt="MyThing> " -- "$@" < <(
find ~/projects -maxdepth 2 -type d
)
}
complete -F _fzf_complete_mything mything

Overriding the Default CTRL-R with Better Options

~/.bashrc - replace default CTRL-R completely
# Remove built-in CTRL-R and set up a better one
if [ -n "$ZSH_VERSION" ]; then
bindkey '^R' fzf-history-widget
else
bind -x '"\C-r": fzf-history-widget'
fi

fzf-history-widget() {
local selected
selected=$(fc -l 1 | tac | awk '!seen[$0]++' |
fzf --scheme=history \
--height=40% \
--reverse \
--tiebreak=index \
--no-sort \
--query="$READLINE_LINE" \
--header='Search shell history' \
--preview='echo {}' \
--preview-window='bottom:3:wrap' \
| sed 's/^ *[0-9]* *//')
READLINE_LINE="$selected"
READLINE_POINT=${#selected}
}

What's Next