How to Implement Custom Fuzzy Completion for Specific Commands in fzf

Use the _fzf_setup_completion function provided in shell/completion.bash to register fuzzy completion for any custom command, or define custom candidate generators using the _fzf_compgen_* naming convention for specialized inputs like Docker containers or Git branches.

The junegunn/fzf repository provides a sophisticated Bash completion system that replaces static tab completion with interactive fuzzy finding. If you want to implement custom fuzzy completion for specific commands, you can leverage the public API exposed in shell/completion.bash without modifying the core fzf source code or the Go binary.

Architecture of fzf's Bash Completion System

The completion system in shell/completion.bash operates through three distinct layers that handle command registration and candidate generation.

Layer 1: Default Completion Bootstrap

The __fzf_default_completion function (lines 41-47) registers a generic fuzzy handler for all commands lacking specific completion definitions. It uses complete -D -F __fzf_default_completion to establish the fallback behavior, ensuring that any command can use fuzzy completion when the trigger pattern is detected.

Layer 2: Command-Specific Registration

For known commands like git, vim, or cd, the __fzf_defc helper (lines 82-92) registers concrete completion functions such as _fzf_path_completion or _fzf_dir_completion. This layer maps specific commands to their appropriate candidate generators using the Bash complete -F builtin.

Layer 3: Public API for Extensions

The _fzf_setup_completion function (lines 200-238) serves as the official entry point for custom fuzzy completion. It dispatches to __fzf_defc with appropriate options based on the completion type: path, dir, var, alias, host, or proc.

Using the Public API: _fzf_setup_completion

The _fzf_setup_completion function provides the simplest method to add fuzzy completion to your custom commands without modifying fzf's source files.

Path Completion for Custom Commands

To enable fuzzy file path completion for a command that accepts file arguments, use the path type:


# In ~/.bashrc, after sourcing fzf's completion.bash

_fzf_setup_completion path mycat myedit mytool

This registers _fzf_path_completion for the specified commands, allowing users to type mycat **<TAB> to trigger fuzzy file selection. The function respects the FZF_COMPLETION_TRIGGER environment variable (defaulting to **).

Directory-Only Completion

For commands that require directory arguments, use the dir type to restrict candidates to directories:

_fzf_setup_completion dir myproj mycd

This invokes _fzf_dir_completion (defined around lines 74-76 in shell/completion.bash), which adds the -o nospace -o dirnames flags to the complete builtin and filters the candidate list to show only directories.

Variable, Alias, and Host Completion

The API supports additional completion types for specific use cases:


# Environment variable completion

_fzf_setup_completion var myenv

# Alias completion

_fzf_setup_completion alias myalias

# SSH host completion

_fzf_setup_completion host myssh

# Process completion (for kill-like commands)

_fzf_setup_completion proc mykill

Each type maps to a specific completion function that generates appropriate candidates (variables from env, hosts from ~/.ssh/known_hosts, processes from ps, etc.).

Advanced: Custom Candidate Generators

When built-in completion types are insufficient, you can define custom candidate generators using the _fzf_compgen_* naming convention.

Implementing a Custom Generator

Define a function following the pattern _fzf_compgen_<name> that outputs candidates one per line:


# Custom generator for Docker containers

_fzf_compgen_docker() {
  docker ps --format '{{.Names}}'
}

Wiring the Generator to Your Command

Use the low-level completion API to connect your generator to a command. The fourth argument to _fzf_setup_completion path specifies the generator suffix:


# Args: type, command, generator suffix, trigger, cmd-placeholder

_fzf_setup_completion path mydocker docker "" ""

Alternatively, invoke the completion machinery directly:

_fzf_complete -m --preview 'docker inspect {}' -- \
  < <(_fzf_compgen_docker)

This bypasses the standard registration and allows custom fzf options like preview windows.

Low-Level API for Fine-Grained Control

For scenarios requiring precise control over fzf flags or completion behavior, use the _fzf_complete function directly.

Direct Invocation Pattern

The _fzf_complete function (lines 146-164 in shell/completion.bash) accepts fzf options followed by a -- separator and a candidate list:


# Example: Custom completion for git branches with preview

_fzf_complete -m --preview 'git log -1 --pretty=oneline {}' \
  -- "--walker=file,dir,follow" < <(
    git branch --all --color=never | sed 's#^\* ##'
  )

Understanding COMPREPLY Population

The completion functions ultimately populate the COMPREPLY array variable that Bash uses to display completion candidates. When _fzf_complete finishes execution, it writes selected items to COMPREPLY, which Bash then inserts into the command line.

Summary

  • Use _fzf_setup_completion as the primary API to register fuzzy completion for custom commands, specifying types like path, dir, var, alias, host, or proc.

  • Define custom generators using the _fzf_compgen_* naming convention when you need to complete non-standard inputs like Docker containers or Git branches.

  • Leverage _fzf_complete directly for advanced scenarios requiring custom fzf flags, preview windows, or specialized candidate filtering.

  • All customization happens in shell/completion.bash—no modifications to the Go source code are necessary, making upgrades safe and configurations portable.

Frequently Asked Questions

How do I trigger fuzzy completion for my custom command?

Type your command followed by the trigger sequence (default is **) and press Tab. For example, mycat **<TAB> opens the fuzzy finder. You can change the trigger by setting the FZF_COMPLETION_TRIGGER environment variable.

Can I use fuzzy completion with commands that already have Bash completions?

Yes. The _fzf_setup_completion function overrides existing completion specifications for the specified commands. It uses complete -F to replace the default completion handler with the fzf fuzzy completion wrapper, preserving the original behavior for non-triggered tabs.

What is the difference between path and dir completion types?

The path type uses _fzf_path_completion which completes both files and directories, while the dir type uses _fzf_dir_completion which restricts candidates to directories only and adds the -o nospace option to prevent Bash from appending a space after directory names, allowing further navigation.

How can I pass extra options to fzf during completion?

For simple cases, set the FZF_COMPLETION_OPTS environment variable to include global options. For command-specific customization, bypass _fzf_setup_completion and call _fzf_complete directly with your desired flags, placing them before the -- separator as shown in the low-level API examples.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →