Files
2026-07-13 09:50:27 +00:00

40 KiB
Raw Permalink Blame History

Note

本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。

fzf - 命令行模糊查找器 构建状态 版本 许可证 贡献者 赞助者 星标


fzf 周边

表达对 fzf 的喜爱——T 恤、马克杯和贴纸现已上架!

commitgoods.com/collections/fzf


fzf 是一款通用命令行模糊查找器(fuzzy finder)和交互式终端工具包。

无论你是选择文件、浏览命令历史、预览数据、 通过模糊匹配浏览复杂数据集,还是创建自定义菜单和 工作流,fzf 都提供了将 shell 脚本转变为丰富 终端应用所需的构建模块。

亮点

  • 便携 // 以单一二进制文件分发,便于安装
  • 快速 // 经过优化,可在毫秒内处理数百万条目
  • 可编程 // 事件驱动架构,用于构建自定义终端界面和工作流
  • 开箱即用 // 内置与 Bash、Zsh、Fish、Nushell、Vim 和 Neovim 的集成

目录

安装

使用 Homebrew

你可以使用 Homebrew(在 macOS 或 Linux 上)安装 fzf。

brew install fzf

Important

要配置 shell 集成(快捷键和模糊补全), 请参阅下方说明

fzf 也可通过 MacPorts 获取:sudo port install fzf

使用 Mise

你可以使用 mise 安装 fzf。

mise use -g fzf@latest

Linux 软件包

软件包管理器 Linux 发行版 命令
APK Alpine Linux sudo apk add fzf
APT Debian 9+/Ubuntu 19.10+ sudo apt install fzf
Conda conda install -c conda-forge fzf
DNF Fedora sudo dnf install fzf
Nix NixOS, etc. nix-env -iA nixpkgs.fzf
Pacman Arch Linux sudo pacman -S fzf
pkg FreeBSD pkg install fzf
pkgin NetBSD pkgin install fzf
pkg_add OpenBSD pkg_add fzf
Portage Gentoo emerge --ask app-shells/fzf
Spack spack install fzf
XBPS Void Linux sudo xbps-install -S fzf
Zypper openSUSE sudo zypper install fzf

Important

要配置 shell 集成(快捷键和模糊补全), 请参阅下方说明

Packaging status

Windows 软件包

在 Windows 上,可通过 ChocolateyScoopWingetMSYS2 安装 fzf

软件包管理器 命令
Chocolatey choco install fzf
Scoop scoop install fzf
Winget winget install fzf
MSYS2 (pacman) pacman -S $MINGW_PACKAGE_PREFIX-fzf

使用 git

或者,你可以将此仓库 "git clone" 到任意目录,然后运行 安装 脚本。

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

安装脚本会向你的 shell 配置文件中添加行,以修改 $PATH 并设置 shell 集成。

二进制发布版

你可以从发布页面下载官方的 fzf 二进制文件。

设置 shell 集成

将以下行添加到你的 shell 配置文件中。

  • bash
    # 设置 fzf 快捷键和模糊补全
    eval "$(fzf --bash)"
    
  • zsh
    # 设置 fzf 快捷键和模糊补全
    source <(fzf --zsh)
    
  • fish
    # 设置 fzf 快捷键
    fzf --fish | source
    
  • Nushell——Nushell 不支持将内容管道到 source,因此安装 脚本会在自动加载目录中生成一个文件。如果你没有使用安装脚本,可以手动设置:
    # 生成集成脚本
    mkdir ($nu.default-config-dir | path join "autoload")
    fzf --nushell | save -f ($nu.default-config-dir | path join "autoload" "_fzf_integration.nu")
    

Note

--bash--zsh--fish--nushell 选项仅适用于 较新版本的 fzf。如果你使用较旧版本的 fzf,或希望进行更精细的控制,可以 引用 /shell 目录中的各个脚本文件。这些 文件的位置可能因你所用的包管理器而异。 请参阅包文档以获取更多信息。 (例如 apt show fzf

Tip

你可以通过在引用脚本时,将对应的 *_COMMAND 变量设为空字符串来禁用 CTRL-T、CTRL-R 或 ALT-C 快捷键。例如,禁用 CTRL-R 和 ALT-C

  • bashFZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --bash)"
  • zshFZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source <(fzf --zsh)
  • fishfzf --fish | FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source
  • nushell:在你的 env.nu 中添加: $env.FZF_CTRL_R_COMMAND = ""; $env.FZF_ALT_C_COMMAND = ""

在引用脚本之后设置变量将不会生效。

Vim/Neovim 插件

如果你使用 vim-plug,),请将以下内容添加到 你的 Vim 配置文件中:

Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
  • junegunn/fzf 提供基础库函数
    • fzf#install() 确保你拥有最新二进制文件
  • junegunn/fzf.vim一个独立项目) 提供各种有用的命令

要了解更多关于 Vim 集成的信息,请参阅 README-VIM.md

Tip

如果你使用 Neovim 并偏好基于 Lua 的插件,请查看 fzf-lua.)

升级 fzf

fzf 正在积极开发中,你可能需要时不时地升级它。请根据你使用的安装方式 按照以下说明操作。

  • gitcd ~/.fzf && git pull && ./install
  • brewbrew update; brew upgrade fzf
  • macportssudo port upgrade fzf
  • chocolateychoco upgrade fzf
  • vim-plug:PlugUpdate fzf

构建 fzf

请参阅 BUILD.md

用法

fzf 会启动交互式查找器,从 STDIN 读取列表,并将选中的项目写入 STDOUT。

find * -type f | fzf > selected

没有 STDIN 管道时,fzf 会遍历当前目录下的文件系统来获取文件列表。

vim $(fzf)

Note

你可以覆盖默认行为

  • 要么将 $FZF_DEFAULT_COMMAND 设置为一个生成所需列表的命令
  • 要么在 $FZF_DEFAULT_OPTS 中设置 --walker--walker-root--walker-skip 选项

Warning

更稳健的解决方案是使用 xargs,但我们展示 了上述方案,因为它更容易理解

fzf --print0 | xargs -0 -o vim

Tip

fzf 还能够将自身转换为另一个进程。

fzf --bind 'enter:become(vim {})'

有关更多信息,请参阅转换为另一个进程

使用查找器

  • CTRL-K / CTRL-J(或 CTRL-P / CTRL-N)上下移动光标
  • Enter 键选择项目,CTRL-C / CTRL-G / ESC 退出
  • 多选模式(-m)下,使用 TABShift-TAB 标记多个项目
  • Emacs 风格快捷键
  • 鼠标:滚动、单击、双击;多选模式下 shift+单击 和 shift+滚动

显示模式

fzf 默认以全屏模式运行,但也有其他显示模式。

--height 模式

使用 --height HEIGHT[%]fzf 将在光标下方以指定高度启动。

fzf --height 40%

reverse 布局和 --border 与此选项搭配效果良好。

fzf --height 40% --layout reverse --border

在高度前加上 ~,可以设置最大高度。

# Will take as few lines as possible to display the list
seq 3 | fzf --height ~100%
seq 3000 | fzf --height ~100%

高度值可以是负数。

# Screen height - 3
fzf --height -3

--popup 模式

使用 --popup 选项,fzf 将在弹出窗口中启动 (需要 tmux 3.3+ 或 Zellij 0.44+)。

# --popup [center|top|bottom|left|right][,SIZE[%]][,SIZE[%][,border-native]]

fzf --popup center         # Center, 50% width and height
fzf --popup 80%            # Center, 80% width and height
fzf --popup 100%,50%       # Center, 100% width and 50% height
fzf --popup left,40%       # Left, 40% width
fzf --popup left,40%,90%   # Left, 40% width, 90% height
fzf --popup top,40%        # Top, 40% height
fzf --popup bottom,80%,40% # Bottom, 80% width, 40% height

当你不处于 tmux 或 Zellij 环境中时,--popup 会被静默忽略。

Note

如果你使用的是不支持弹出窗口的旧版 tmux, 或者你想在常规 tmux 窗格中打开 fzf,请查看 fzf-tmux 脚本。

Tip

你可以将这些选项添加到 $FZF_DEFAULT_OPTS 中,以便默认应用它们。 例如,

# 如果在 tmux 或 Zellij 中则在弹出窗口中打开,否则使用 --height 模式
export FZF_DEFAULT_OPTS='--height 40% --popup bottom,40% --layout reverse --border top'

搜索语法

除非另有指定,fzf 以"扩展搜索模式"启动,你可以输入多个以空格分隔的搜索词。例如 ^music .mp3$ sbtrkt !fire

标记 匹配类型 描述
sbtrkt 模糊匹配 匹配 sbtrkt 的项目
'wild 精确匹配(带引号) 包含 wild 的项目
'wild' 精确边界匹配(两端均带引号) 在单词边界处包含 wild 的项目
^music 前缀精确匹配 music 开头的项目
.mp3$ 后缀精确匹配 .mp3 结尾的项目
!fire 反向精确匹配 不包含 fire 的项目
!^music 反向前缀精确匹配 不以 music 开头的项目
!.mp3$ 反向后缀精确匹配 不以 .mp3 结尾的项目

如果你不喜欢模糊匹配且不希望给每个词加引号, 请使用 -e--exact 选项启动 fzf。注意,当设置了 --exact 时,' 前缀会"取消引号"该词条。

单个竖线字符词条充当 OR 运算符。例如,以下查询匹配以 core 开头 且以 gorbpy 结尾的条目。

^core go$ | rb$ | py$

环境变量

  • FZF_DEFAULT_COMMAND
    • 当输入为 tty 时使用的默认命令
    • 例如 export FZF_DEFAULT_COMMAND='fd --type f'
  • FZF_DEFAULT_OPTS
    • 默认选项
    • 例如 export FZF_DEFAULT_OPTS="--layout=reverse --inline-info"
  • FZF_DEFAULT_OPTS_FILE
    • 如果你更倾向于在文件中管理默认选项,请将此变量设置为 指向该文件的位置
    • 例如 export FZF_DEFAULT_OPTS_FILE=~/.fzfrc

Warning

FZF_DEFAULT_COMMAND 未被 shell 集成使用,因为需求略有差异。

  • CTRL-T 运行 $FZF_CTRL_T_COMMAND 以获取文件和目录列表
  • ALT-C 运行 $FZF_ALT_C_COMMAND 以获取目录列表
  • vim ~/**<tab> 以前缀(~/)作为第一个参数运行 fzf_compgen_path()
  • cd foo**<tab> 以前缀(foo)作为第一个参数运行 fzf_compgen_dir()

可用选项详见本文档后续内容。

自定义外观

fzf 的用户界面可通过大量配置选项进行完全自定义。如需快速设置,你可以使用 defaultfullminimal 等样式预设之一,通过 --style 选项启动。

fzf --style full \
    --preview 'fzf-preview.sh {}' --bind 'focus:transform-header:file --brief {}'
预设 截图
default
full
minimal

以下是一个基于 full 预设的示例:

git ls-files | fzf --style full \
    --border --padding 1,2 \
    --border-label ' Demo ' --input-label ' Input ' --header-label ' File Type ' \
    --preview 'fzf-preview.sh {}' \
    --bind 'result:transform-list-label:
        if [[ -z $FZF_QUERY ]]; then
          echo " $FZF_MATCH_COUNT items "
        else
          echo " $FZF_MATCH_COUNT matches for [$FZF_QUERY] "
        fi
        ' \
    --bind 'focus:transform-preview-label:[[ -n {} ]] && printf " Previewing [%s] " {}' \
    --bind 'focus:+transform-header:file --brief {} || echo "No file selected"' \
    --bind 'ctrl-r:change-list-label( Reloading the list )+reload(sleep 2; git ls-files)' \
    --color 'border:#aaaaaa,label:#cccccc' \
    --color 'preview-border:#9999cc,preview-label:#ccccff' \
    --color 'list-border:#669966,list-label:#99cc99' \
    --color 'input-border:#996666,input-label:#ffcccc' \
    --color 'header-border:#6699cc,header-label:#99ccff'

选项

请查阅手册(fzf --manman fzf)获取完整选项列表。

演示

如果你喜欢通过视频学习,可以观看 @samoshkin) 制作的这个录屏,探索 fzf 的各项功能。

示例

命令行按键绑定

通过设置 shell 集成,你可以在 bash、zsh、fish 和 Nushell 中使用以下按键绑定。

  • CTRL-T - 将选中的文件和目录粘贴到命令行中
    • 列表通过 --walker file,dir,follow,hidden 选项生成
      • 你可以通过设置 FZF_CTRL_T_COMMAND 为自定义命令来覆盖默认行为
      • 或者你可以在 FZF_CTRL_T_OPTS 中设置 --walker* 选项
    • 设置 FZF_CTRL_T_OPTS 以向 fzf 传递额外选项
      # 使用 bat 预览文件内容(https://github.com/sharkdp/bat)
      export FZF_CTRL_T_OPTS="
        --walker-skip .git,node_modules,target
        --preview 'bat -n --color=always {}'
        --bind 'ctrl-/:change-preview-window(down|hidden|)'"
      
    • 可以通过在加载脚本时将 FZF_CTRL_T_COMMAND 设为空字符串来禁用
  • CTRL-R - 将选中的历史命令粘贴到命令行中。
    • 使用 TAB 选择多条命令。
    • 如果想按时间顺序查看命令,再次按下 CTRL-R 可切换为按相关性排序
    • 按下 ALT-R 切换"原始"模式,可查看匹配项周围的上下文。在该模式下,按下 CTRL-NCTRL-P 仅在匹配项之间移动。
    • 按下 CTRL-/ALT-/ 切换自动换行
    • 按下 SHIFT-DELETE 删除选中的命令(bash 和 fish)
    • 仅限 Fish shell
      • 按下 ALT-ENTER 重新格式化并插入选中的命令
      • 按下 ALT-T 循环切换命令前缀(时间戳、日期/时间、无)
    • 设置 FZF_CTRL_R_OPTS 以向 fzf 传递额外选项
      # CTRL-Y 使用 pbcopy 将命令复制到剪贴板
      export FZF_CTRL_R_OPTS="
        --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
        --color header:italic
        --header 'Press CTRL-Y to copy command into clipboard'"
      
      # Fish shell:设置日期/时间为默认前缀
      set -gx FZF_CTRL_R_OPTS "--with-nth 1,3.. --bind 'alt-t:change-with-nth(2..|3..|1,3..)'"
      
      # 或默认不显示前缀
      set -gx FZF_CTRL_R_OPTS "--with-nth 3.. --bind 'alt-t:change-with-nth(2..|1,3..|3..)'"
      
    • 可以通过在加载脚本时将 FZF_CTRL_R_COMMAND 设为空字符串来禁用
    • 通过非空的 FZF_CTRL_R_COMMAND 进行自定义覆盖暂不支持,会发出警告
  • ALT-C - 进入选中的目录
    • 列表通过 --walker dir,follow,hidden 选项生成
    • 设置 FZF_ALT_C_COMMAND 以覆盖默认命令
      • 或者你可以在 FZF_ALT_C_OPTS 中设置 --walker-* 选项
    • 设置 FZF_ALT_C_OPTS 以向 fzf 传递额外选项
      # 在预览窗口中打印树形结构
      export FZF_ALT_C_OPTS="
        --walker-skip .git,node_modules,target
        --preview 'tree -C {}'"
      
    • 可以通过在加载脚本时将 FZF_ALT_C_COMMAND 设为空字符串来禁用

这些绑定的显示模式可通过 FZF_{CTRL_T,CTRL_R,ALT_C}_OPTS 单独配置,或通过 FZF_DEFAULT_OPTS 全局配置。 (例如:FZF_CTRL_R_OPTS='--popup bottom,60% --height 60% --border top'

更多技巧请参见 Wiki 页面.)

模糊补全

Shell 集成还为 bash、zsh、fish 和 Nushell 提供了模糊补全功能。

文件和目录

如果光标前的单词以触发序列结尾(默认为 **),则可触发文件和目录的模糊补全。

  • COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TAB>
# Files under the current directory
# - You can select multiple items with TAB key
vim **<TAB>

# Files under parent directory
vim ../**<TAB>

# Files under parent directory that match `fzf`
vim ../fzf**<TAB>

# Files under your home directory
vim ~/**<TAB>


# Directories under current directory (single-selection)
cd **<TAB>

# Directories under ~/github that match `fzf`
cd ~/github/fzf**<TAB>

进程 ID

为 kill 命令提供了 PID 的模糊补全。

# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 **<TAB>

主机名

为 ssh 命令提供了主机名的模糊补全。主机名从 /etc/hosts 和 ~/.ssh/config 中提取。

ssh **<TAB>

环境变量 / 别名

# bash and zsh
unset **<TAB>
export **<TAB>
unalias **<TAB>

# fish
set <SHIFT-TAB>

自定义 bash 和 zsh 的模糊补全

自定义补全的 fzf 选项

# Use ~~ as the trigger sequence instead of the default **
export FZF_COMPLETION_TRIGGER='~~'

# Options to fzf command
export FZF_COMPLETION_OPTS='--border --info=inline'

# Options for path completion (e.g. vim **<TAB>)
export FZF_COMPLETION_PATH_OPTS='--walker file,dir,follow,hidden'

# Options for directory completion (e.g. cd **<TAB>)
export FZF_COMPLETION_DIR_OPTS='--walker dir,follow'

# Advanced customization of fzf options via _fzf_comprun function
# - The first argument to the function is the name of the command.
# - You should make sure to pass the rest of the arguments ($@) to fzf.
_fzf_comprun() {
  local command=$1
  shift

  case "$command" in
    cd)           fzf --preview 'tree -C {} | head -200'   "$@" ;;
    export|unset) fzf --preview "eval 'echo \$'{}"         "$@" ;;
    ssh)          fzf --preview 'dig {}'                   "$@" ;;
    *)            fzf --preview 'bat -n --color=always {}' "$@" ;;
  esac
}

自定义路径和目录的补全来源

# Use fd (https://github.com/sharkdp/fd) for listing path candidates.
# - The first argument to the function ($1) is the base path to start traversal
# - See the source code (completion.{bash,zsh}) for the details.
_fzf_compgen_path() {
  fd --hidden --follow --exclude ".git" . "$1"
}

# Use fd to generate the list for directory completion
_fzf_compgen_dir() {
  fd --type d --hidden --follow --exclude ".git" . "$1"
}

支持的命令(bash

在 bash 中,模糊补全仅对预定义的命令集生效 (可通过 complete | grep _fzf 查看列表)。但你也可以使用 _fzf_setup_completion 辅助函数为其他命令启用模糊补全。

# usage: _fzf_setup_completion path|dir|var|alias|host COMMANDS...
_fzf_setup_completion path ag git kubectl
_fzf_setup_completion dir tree

自定义模糊补全

(自定义补全 API 处于实验阶段,可能发生变更)

对于名为 "COMMAND" 的命令,使用 _fzf_complete 辅助函数定义 _fzf_complete_COMMAND 函数。

# Custom fuzzy completion for "doge" command
#   e.g. doge **<TAB>
_fzf_complete_doge() {
  _fzf_complete --multi --reverse --prompt="doge> " -- "$@" < <(
    echo very
    echo wow
    echo such
    echo doge
  )
}
  • -- 之前的参数是传递给 fzf 的选项。
  • -- 之后,只需原封不动地传递原始的补全参数("$@")。
  • 然后,编写一组命令来生成补全候选,并通过进程替换(< <(...) 将其输出送入该函数。

zsh 会根据命名约定自动识别该函数,但在 bash 中,你需要使用 complete 命令手动将函数与命令关联。

[ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge

如果你需要对 fzf 的输出进行后处理,可以按如下方式定义 _fzf_complete_COMMAND_post

_fzf_complete_foo() {
  _fzf_complete --multi --reverse --header-lines=3 -- "$@" < <(
    ls -al
  )
}

_fzf_complete_foo_post() {
  awk '{print $NF}'
}

[ -n "$BASH" ] && complete -F _fzf_complete_foo -o default -o bashdefault foo

Fish 的模糊补全

Fish 的模糊补全与 bash 和 zsh 的区别在于:

  • 它不需要像 ** 这样的触发序列。相反,它在 Shift-TAB 上激活(替代原生分页器搜索模式),而 TAB 保留 fish 的原生补全行为。
  • 它依赖 fish 的原生补全系统来生成候选列表,而非执行递归的文件系统遍历。如需递归搜索, 请改用 CTRL-T 绑定。
  • 如果当前命令行令牌是通配符模式,它会在通配符展开路径列表上执行搜索(而非将 所有结果插入命令行的原生行为)。由于展开由 shell 执行,结果数量存在上限。
  • 仅支持的配置变量是 FZF_COMPLETION_OPTSFZF_EXPANSION_OPS
  • 自定义补全函数所使用的函数名为 fzf_complete,它只接受 fzf 选项作为参数,也可以在没有任何重定向输入的情况下调用, 仅用于修改 fzf 选项同时呈现原生补全结果。为了与其他 shell 兼容, 提供了名为 _fzf_complete 的函数,它在 fzf 选项之后可以接受命令行参数中的 -- $argv

对于 fish 补全覆盖不到的命令,最好创建常规的 fish 补全函数(这对 TABShift-TAB 都有效),并仅在需要修改特定命令的 fzf 选项或希望 Shift-TAB 获得不同结果时才创建 fzf 补全函数:

# Customize git completion
function _fzf_complete_git
  # Show header text with active branch for all git completions
  set -lx -- FZF_COMPLETION_OPTS --header="'"(git branch --show-current 2>/dev/null)"'"

  # No other changes when less than 3 arguments, or when completing options
  if not set -q argv[3]; or string match -q -- '-*' $argv[-1]
    fzf_complete
    return
  end

  # Check subcommand
  switch $argv[2]
    case checkout diff log show
      # Set preview and display all branches and commits for subcommands: checkout, diff, log, show
      begin
        git branch --all --format='%(refname:short)'
        git log --all --oneline --color=always
      end | fzf_complete --no-multi --ansi --accept-nth=1 --query=$argv[-1] --preview='git show --color=always {1}'

    case add rm mv
      # Only set preview for subcommands: add, rm, mv
      # Special characters in fish completion lists are escaped, so the r flag must be used.
      fzf_complete --preview="git diff --color=always {r1}"

    case '*'
      # No changes for other subcommands
      fzf_complete
  end
end

与 bash 和 zsh 类似,可以通过定义一个名为 _fzf_complete_COMMAND_post_fzf_post_complete_COMMAND 的函数来对 fzf 的输出进行处理后再插入命令行:

function _fzf_complete_foo
  ls -sh --zero --color=always | fzf_complete --read0 --print0 --ansi --no-multi-line --header-lines=1
end

function _fzf_post_complete_foo
  while read -lz result
    string escape -n -- $result | string trim -l -c '\ ' | string split -m 1 -f 2 ' '
  end
end

Nushell 的模糊补全

Nushell 中的模糊补全通过 外部补全器) 机制实现。与 bash 和 zsh 相比存在一些差异:

  • 在 Nushell >= 0.103.0 上,内置命令(例如 cdls)不再调用外部补全器。使用 **<TAB> 的模糊补全仅对外部命令生效。
  • 自定义补全器可以通过 $env.FZF_COMPLETERS 记录在你的 config.nu 中定义。每个条目是一个闭包,接收前缀和命令跨度,返回候选字符串列表或包含自定义 fzf 选项的记录 { candidates: [...], opts: [...] }
    $env.FZF_COMPLETERS = {
        pacman: {|prefix, spans|
            let sub = $spans | skip 1 | first
            let candidates = (if ($sub =~ "-[SF]") { ^pacman -Slq | lines
            } else if ($sub =~ "-[QR]") { ^pacman -Qq | lines
            } else { [] })
            { candidates: $candidates, opts: ["--preview", "pacman -Si {}"] }
        }
    }
    
    更多示例请参见 shell/completion-examples.nu
  • 支持以下环境变量: FZF_COMPLETION_TRIGGERFZF_COMPLETION_OPTSFZF_COMPLETION_PATH_OPTSFZF_COMPLETION_DIR_OPTSFZF_COMPLETION_DIR_COMMANDS

Vim 插件

参见 README-VIM.md

高级主题

针对不同类型输入的自定义

由于 fzf 是一个通用的文本过滤器,其算法设计为"一般"能很好地适用于任何类型的输入。但不可否认,没有真正通用的解决方案,你可能需要根据输入类型调整算法和一些设置。为简化这一过程,fzf 为几种常见输入类型提供了一套"方案"。

方案 描述
--scheme=default 通用方案,设计为能很好地适用于任何类型的输入
--scheme=path 适用于文件路径
--scheme=history 适用于命令历史或任何按时间顺序排列重要的输入

(详见 fzf --man

性能

fzf 很快。在大多数使用场景中性能不应成为问题。不过,你可能需要注意那些会影响性能的选项。

  • --ansi 告知 fzf 提取并解析输入中的 ANSI 颜色代码,这会使初始扫描变慢。因此不建议将其加入 $FZF_DEFAULT_OPTS
  • --nth 会使 fzf 变慢,因为它需要对每一行进行分词。
  • 纯字符串 --delimiter 应优先于正则表达式分隔符。
  • --with-nth 会使 fzf 变慢,因为它需要对每一行进行分词并重新组装。

执行外部程序

你可以设置按键绑定,在不离开 fzf 的情况下启动外部进程(executeexecute-silent)。

# Press F1 to open the file with less without leaving fzf
# Press CTRL-Y to copy the line to clipboard and aborts fzf (requires pbcopy)
fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort'

详情请参阅手册的按键/事件绑定章节。

切换为另一个进程

become(...) 与上文介绍的 execute(...)/execute-silent(...) 类似,不同之处在于它不会执行命令后返回 fzf,而是将 fzf 切换为执行该命令的新进程。

fzf --bind 'enter:become(vim {})'

与看似等效的命令替换 vim "$(fzf)" 相比,这种方式有几个优势:

  • 当用 CTRL-C 终止 fzf 时,Vim 不会打开空文件
  • 当在空结果上按 ENTER 时,Vim 不会打开空文件
  • 可以处理多项选择,即使其中包含空格
    fzf --multi --bind 'enter:become(vim {+})'
    

公平地说,使用 fzf --print0 | xargs -0 -o vim 代替 vim "$(fzf)" 可以解决上述所有问题。尽管如此,become(...) 在不同场景下仍提供了额外优势。

  • 你可以设置多个绑定,以不同方式处理结果,而无需任何包装脚本
    fzf --bind 'enter:become(vim {}),ctrl-e:become(emacs {})'
    
    • 之前,你需要使用 --expect=ctrl-e 并检查 fzf 输出的第一行
  • 你可以利用 fzf 的字段索引表达式轻松构建后续命令
    # 在 Vim 中打开文件并跳转到指定行
    git grep --line-number . |
        fzf --delimiter : --nth 3.. --bind 'enter:become(vim {1} +{2})'
    

重新加载候选列表

通过将 reload 操作绑定到某个按键或事件,你可以让 fzf 动态重新加载候选列表。详情请参见 https://github.com/junegunn/fzf/issues/1750

1. 按 CTRL-R 更新进程列表

ps -ef |
  fzf --bind 'ctrl-r:reload(ps -ef)' \
      --header 'Press CTRL-R to reload' --header-lines=1 \
      --height=50% --layout=reverse

2. 按 CTRL-D 或 CTRL-F 切换源

FZF_DEFAULT_COMMAND='find . -type f' \
  fzf --bind 'ctrl-d:reload(find . -type d),ctrl-f:reload(eval "$FZF_DEFAULT_COMMAND")' \
      --height=50% --layout=reverse

3. 交互式 ripgrep 集成

以下示例将 fzf 作为 ripgrep 的选择器界面。我们将 reload 操作绑定到 change 事件,这样每当你在 fzf 中输入时,ripgrep 进程都会重新启动,并使用占位符表达式 {q} 表示更新后的查询字符串。另外,注意我们使用了 --disabled 选项,使 fzf 不执行任何二次过滤。

: | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \
    fzf --bind 'start:reload:$rg_prefix ""' \
        --bind 'change:reload:$rg_prefix {q} || true' \
        --bind 'enter:become(vim {1} +{2})' \
        --ansi --disabled \
        --height=50% --layout=reverse

如果 ripgrep 没有找到任何匹配项,它将以非零退出码退出,fzf 会对此发出警告。要抑制该警告信息,我们为命令添加了 || true,使其始终以 0 退出。

更复杂的示例请参见 "Using fzf as interactive Ripgrep launcher"`)。

预览窗口

设置 --preview 选项后,fzf 会自动启动一个外部进程,将当前行作为参数传入,并在拆分窗口中显示结果。你的 $SHELL 用于执行该命令,$SHELL -c COMMAND 作为参数传入。可以使用鼠标或自定义按键绑定来滚动窗口。

# {} is replaced with the single-quoted string of the focused line
fzf --preview 'cat {}'

预览窗口支持 ANSI 颜色,因此你可以使用任何能够对文件内容进行语法高亮的程序,例如 Bat) 或 [Highlight](https://gitlab.com/saalen/highlight):`)。

fzf --preview 'bat --color=always {}' --preview-window '~3'

你可以使用 --preview-window 选项自定义预览窗口的大小、位置和边框,使用 --color 选项自定义其前景色和背景色。例如:

fzf --height 40% --layout reverse --info inline --border \
    --preview 'file {}' --preview-window up,1,border-horizontal \
    --bind 'ctrl-/:change-preview-window(50%|hidden|)' \
    --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'

完整选项列表请参阅手册(man fzf)。

更多高级示例请参见此处.`)。

Warning

由于 fzf 是通用文本过滤器而非文件查找器,不建议将 --preview 选项加入你的 $FZF_DEFAULT_OPTS

# *********************
# ** 不要这样做!**
# *********************
export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"'

# bat 不适用于除文件列表以外的任何输入
ps -ef | fzf
seq 100 | fzf
history | fzf

预览图片

fzf 可以通过以下协议之一在预览窗口中显示图片:

  • Kitty 图形协议`)
  • iTerm2 内联图片协议`)
  • Sixel`)

更多信息请参见 bin/fzf-preview.sh 脚本。

fzf --preview 'fzf-preview.sh {}'

技巧

遵守 .gitignore

你可以使用 fd,)、[ripgrep](https://github.com/BurntSushi/ripgrep),) 或 [The Silver Searcher](https://github.com/ggreer/the_silver_searcher)`) 来遍历文件系统,同时遵守 .gitignore

# Feed the output of fd into fzf
fd --type f --strip-cwd-prefix | fzf

# Setting fd as the default source for fzf
export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix'

# Now fzf (w/o pipe) will use the fd command to generate the list
fzf

# To apply the command to CTRL-T as well
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"

如果你希望命令跟随符号链接且不排除隐藏文件,请使用以下命令:

export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git'

Fish shell

与 bash 和 zsh 不同,fish 的 CTRL-T 按键绑定会将命令行上的最后一个 token 作为递归搜索的根目录。例如,在以下命令行的末尾按下 CTRL-T

ls /var/

将列出 /var/ 下的所有文件和目录。

使用自定义 FZF_CTRL_T_COMMAND 时,请使用未展开的 $dir 变量来利用此功能。当最后一个 token 不是有效目录时,$dir 默认为 .。示例:

set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"

fzf 主题游乐场

fzf 主题游乐场) 由 [Vitor Mello](https://github.com/vitormv)`) 创建,是一个可以交互式创建 fzf 主题的网页。

相关项目

https://github.com/junegunn/fzf/wiki/Related-projects

License

MIT 许可证 (MIT)

Copyright (c) 2013-2026 Junegunn Choi

Goods

在此获取 fzf T 恤、马克杯和贴纸:https://commitgoods.com/collections/fzf

Sponsors ❤️

我要感谢本项目的所有赞助商,是他们让我能够继续改进 fzf。

如果你想赞助本项目,请访问 https://github.com/sponsors/junegunn.