Custom Shell Completions
Beyond the built-in ** completion trigger for standard commands, you can create fully custom fzf completions for any command.
How Shell Completion Works with fzf
When you press <Tab> after **, fzf intercepts the completion event and calls your custom _fzf_complete_COMMAND function.
Writing a Custom Completion
Bash Completion Function
~/.bashrc
# Custom completion for a command called 'deploy'
_fzf_complete_deploy() {
# $@ contains the current command line tokens
_fzf_complete --multi --prompt="Environment> " -- "$@" < <(
# Produce the list of completions
echo "development"
echo "staging"
echo "production-us-east"
echo "production-eu-west"
)
}
# Register the completion
complete -F _fzf_complete_deploy deploy
Post-process the Selection
# The _fzf_complete_deploy_post function transforms the selected value
_fzf_complete_deploy_post() {
# Read from stdin, transform, write to stdout
awk '{print $1}' # take only first column
}
Real-World: kubectl Completion
~/.bashrc
# Pick kubernetes contexts with fzf
_fzf_complete_kubectl() {
if [[ $COMP_LINE == *"kubectl config use-context"* ]]; then
_fzf_complete --prompt="Context> " -- "$@" < <(
kubectl config get-contexts -o name 2>/dev/null
)
else
_fzf_complete -- "$@" < <(
kubectl get all --all-namespaces 2>/dev/null | awk '{print $1"/"$2}'
)
fi
}
complete -F _fzf_complete_kubectl kubectl
Real-World: SSH Completion Enhanced
~/.bashrc
_fzf_complete_ssh() {
_fzf_complete --prompt="Host> " -- "$@" < <(
{
# From known_hosts
cat ~/.ssh/known_hosts 2>/dev/null | awk '{print $1}' | tr ',' '\n'
# From config hosts
grep -E "^Host " ~/.ssh/config 2>/dev/null | awk '{print $2}'
} | grep -v '\*' | sort -u
)
}
complete -F _fzf_complete_ssh ssh
Real-World: Git Branch Completion
~/.bashrc
_fzf_complete_git() {
local subcommand="${COMP_WORDS[1]}"
case "$subcommand" in
checkout|co|switch|merge|rebase|cherry-pick|branch)
_fzf_complete --prompt="Branch> " -- "$@" < <(
git branch --all 2>/dev/null | grep -v HEAD | sed 's/^[* ]*//' | sed 's#remotes/origin/##' | sort -u
)
;;
*)
_fzf_complete_git_default "$@"
;;
esac
}
complete -F _fzf_complete_git git
Zsh Custom Completions
~/.zshrc
# Zsh: override completion for 'deploy'
_fzf_complete_deploy() {
_fzf_complete -- "$@" < <(
print -l development staging production
)
}
Triggering Custom Completion
By default, **<Tab> triggers fzf completion. Override the trigger:
~/.bashrc
export FZF_COMPLETION_TRIGGER='~~' # Use ~~ instead of **
# Now: vim ~~<Tab> triggers fzf