关于 fzf
fzf 是一个通用模糊查找工具,用于快速交互式搜索文件、命令历史、进程等。通过 find . -type f | fzf 搜索文件,history | fzf 查找历史命令,集成到编码 Agent 的工作流中。
主要功能
- 01通过模糊匹配快速搜索和过滤文件列表
- 02从命令历史中交互式搜索和重新执行之前的命令
- 03与 Unix 管道结合搜索任意数据源的内容
适用场景
- 01编码 Agent 快速定位和选择项目文件
- 02开发者在命令历史中查找和重新使用之前的命令
- 03与其他工具集成构建交互式的数据查询工作流
安装
选择你的系统或包管理器,复制命令到终端运行。
安装完成后运行fzf --version确认安装成功。
命令示例
常用命令按使用顺序排列。
详细介绍
表达你对 fzf 的喜爱——T 恤、马克杯和贴纸现已开售!
fzf 是一款通用命令行模糊查找器,也是一个交互式终端工具包。
无论是选择文件、浏览命令历史记录、预览数据,还是通过模糊匹配浏览复杂数据集,或创建自定义菜单和工作流,fzf 都能提供所需的基础组件,将 Shell 脚本转变为功能丰富的终端应用。
亮点
- 便携 // 以单个二进制文件分发,便于安装
- 快速 // 经过优化,可在毫秒内处理数百万个条目
- 可编程 // 采用事件驱动架构,可用于构建自定义终端界面和工作流
- 功能齐全 // 内置 Bash、Zsh、Fish、Nushell、Vim 和 Neovim 集成
目录
安装
使用 Homebrew
你可以使用 Homebrew(在 macOS 或 Linux 上)安装 fzf。
brew install fzf
重要
如需设置 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 |
重要
如需设置 Shell 集成(快捷键绑定和模糊补全), 请参阅下方说明。
Windows 软件包
在 Windows 上,可通过 Chocolatey、Scoop、 Winget 和 MSYS2 获取 fzf:
| 软件包管理器 | 命令 |
|---|---|
| Chocolatey | choco install fzf |
| Scoop | scoop install fzf |
| Winget | winget install fzf |
| MSYS2 (pacman) | pacman -S $MINGW_PACKAGE_PREFIX-fzf |
使用 git
或者,你可以将此仓库“git clone”到任意目录,然后运行 install 脚本。
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
安装脚本会在 Shell 配置文件中添加几行内容,以修改
$PATH 并设置 Shell 集成。
二进制发行版
你可以从发行版页面下载官方 fzf 二进制文件。
设置 Shell 集成
将以下行添加到 Shell 配置文件中。
- bash
# Set up fzf key bindings and fuzzy completion eval "$(fzf --bash)" - zsh
# Set up fzf key bindings and fuzzy completion source <(fzf --zsh) - fish
# Set up fzf key bindings fzf --fish | source - Nushell -- Nushell 不支持通过管道传入
source,因此安装脚本会在自动加载目录中生成一个文件。如果你没有使用安装脚本,可以手动进行设置:# Generate the integration script mkdir ($nu.default-config-dir | path join "autoload") fzf --nushell | save -f ($nu.default-config-dir | path join "autoload" "_fzf_integration.nu")
说明
--bash、--zsh、--fish和--nushell选项仅在较新版本的 fzf 中可用。如果你使用的是较旧版本的 fzf,或者想要更精细地控制,可以在 /shell 目录中加载单独的脚本文件。文件的位置可能因所用包管理器而异。更多信息请参阅相应的包文档。 (例如apt show fzf)
提示
加载脚本时,将相应的
*_COMMAND变量设为空字符串,即可禁用 CTRL-T、CTRL-R 或 ALT-C 快捷键绑定。例如,要禁用 CTRL-R 和 ALT-C:
- bash:
FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --bash)"- zsh:
FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source <(fzf --zsh)- fish:
fzf --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。
提示
如果你使用 Neovim,并且偏好基于 Lua 的插件,可以试试 fzf-lua。
升级 fzf
fzf 正在积极开发中,你可能需要不时升级。请根据所用的安装方式,按照以下说明操作。
- git:
cd ~/.fzf && git pull && ./install - brew:
brew update; brew upgrade fzf - macports:
sudo port upgrade fzf - chocolatey:
choco upgrade fzf - vim-plug:
:PlugUpdate fzf
构建 fzf
请参阅 BUILD.md。
用法
fzf 会启动交互式查找器,从 STDIN 读取列表,并将选中的条目写入 STDOUT。
find * -type f | fzf > selected
如果没有 STDIN 管道,fzf 会遍历当前目录下的文件系统以获取文件列表。
vim $(fzf)
说明
你可以通过以下方式覆盖默认行为:
- 将
$FZF_DEFAULT_COMMAND设为生成所需列表的命令- 或在
$FZF_DEFAULT_OPTS中设置--walker、--walker-root和--walker-skip选项
警告
使用
xargs会更稳妥,但这里提供上述方式是因为它更容易理解fzf --print0 | xargs -0 -o vim
提示
fzf 也可以将自身转换为另一个进程。
fzf --bind 'enter:become(vim {})'更多信息请参阅转换为另一个进程。
使用查找器
- 使用
CTRL-K/CTRL-J(或CTRL-P/CTRL-N)上下移动光标 - 按
Enter选择条目,按CTRL-C/CTRL-G/ESC退出 - 在多选模式(
-m)下,使用TAB和Shift-TAB标记多个条目 - Emacs 风格的按键绑定
- 鼠标:滚动、单击、双击;在多选模式下按住 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 会被静默忽略。
说明
如果你只能使用不支持弹出窗口的旧版 tmux, 或者想在常规 tmux 窗格中打开 fzf,请查看 fzf-tmux 脚本。
提示
你可以将这些选项添加到
$FZF_DEFAULT_OPTS,以便默认应用。例如:# 在 tmux 或 Zellij 中以弹出窗口打开,否则使用 --height 模式 export FZF_DEFAULT_OPTS='--height 40% --popup bottom,40% --layout reverse --border top'
搜索语法
除非另有说明,fzf 会以“扩展搜索模式”启动,你可以输入多个由空格分隔的搜索词。例如:^music .mp3$ sbtrkt !fire
| Token | 匹配类型 | 说明 |
|---|---|---|
sbtrkt | 模糊匹配 | 匹配 sbtrkt 的条目 |
'wild | 精确匹配(引号开头) | 包含 wild 的条目 |
'wild' | 精确边界匹配(两端加引号) | 在单词边界处包含 wild 的条目 |
^music | 前缀精确匹配 | 以 music 开头的条目 |
.mp3$ | 后缀精确匹配 | 以 .mp3 结尾的条目 |
!fire | 反向精确匹配 | 不包含 fire 的条目 |
!^music | 反向前缀精确匹配 | 不以 music 开头的条目 |
!.mp3$ | 反向后缀精确匹配 | 不以 .mp3 结尾的条目 |
如果你不喜欢模糊匹配,也不想给每个词都加“引号”,
可以使用 -e 或 --exact 选项启动 fzf。请注意,设置 --exact 时,
' 前缀会取消该词的引号含义。
单个竖线字符词项会充当 OR 运算符。例如,以下查询会匹配以 core 开头,
并以 go、rb 或 py 结尾的条目。
^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
警告
Shell 集成不会使用
FZF_DEFAULT_COMMAND,因为其要求略有不同。
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 的用户界面支持通过大量配置选项进行完全自定义。如需快速设置,可以使用 --style 选项,从 default、full 或 minimal 这几种样式预设中选择一种。
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'
选项
完整选项列表请参阅 man 页面(fzf --man 或 man fzf)。
演示
如果你喜欢通过观看视频来学习,可以查看 @samoshkin 制作的屏幕录制视频,了解 fzf 的功能。
示例
- 示例 Wiki 页面
- 免责声明:此页面上的示例由社区维护,未经全面测试
- 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-N和CTRL-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 '按 CTRL-Y 将命令复制到剪贴板'"# 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..)'" - 在 source 脚本时,将
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 {}'" - 在 source 脚本时,将
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')
更多技巧请参阅维基页面。
模糊补全
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_OPTS和FZF_EXPANSION_OPS。 - 自定义补全函数使用的函数名为
fzf_complete,它只接受 fzf 选项作为参数;也可以在没有重定向输入的情况下调用,仅修改 fzf 选项,同时显示原生补全结果。为兼容其他 shell,还提供了名为_fzf_complete的函数,可在命令行参数中的 fzf 选项之后接受-- $argv。
对于 fish 补全未覆盖的命令,最好创建常规的 fish 补全函数(同时适用于 TAB 和 Shift-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.116.1 或更新版本。补全会在线编辑器线程上运行,以便 fzf 获取终端;因此,如果没有
**触发符,之前配置的外部补全器(例如 Carapace)会以内联方式调用。 - 该脚本会封装加载时配置的外部补全器,因此应在设置其他外部补全器之后加载。上文所述的自动加载设置会在
config.nu之后运行,因此已经满足这一要求。 - 在 Nushell >= 0.103.0 中,内置命令(例如
cd、ls)不再调用外部补全器。**<TAB>模糊补全仅适用于外部命令。 - 可以通过
config.nu中的$env.FZF_COMPLETERS记录定义自定义补全器。每个条目都是一个闭包,接收前缀和命令跨度,并返回候选字符串列表,或用于自定义 fzf 选项的记录{ candidates: [...], opts: [...] }:
更多示例请参阅 shell/completion-examples.nu。$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 {}"] } } } - 支持以下环境变量:
FZF_COMPLETION_TRIGGER、FZF_COMPLETION_OPTS、FZF_COMPLETION_PATH_OPTS、FZF_COMPLETION_DIR_OPTS、FZF_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 必须对每一行进行分词并重新组合。
执行外部程序
你可以设置快捷键绑定,在不退出 fzf 的情况下启动外部进程(execute、execute-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'
详情请参阅手册页中的 KEY/EVENT BINDINGS 章节。
转换为其他进程
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 的字段索引表达式构建后续命令
# Open the file in Vim and go to the line 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 退出。
更复杂的示例请参阅“将 fzf 用作交互式 Ripgrep 启动器”。
预览窗口
设置 --preview 选项后,fzf 会自动启动一个外部进程,将当前行作为参数传递给该进程,并在分屏窗口中显示结果。执行命令时会使用你的 $SHELL,形式为 $SHELL -c COMMAND。可以使用鼠标或自定义按键绑定滚动窗口。
# {} is replaced with the single-quoted string of the focused line
fzf --preview 'cat {}'
预览窗口支持 ANSI 颜色,因此你可以使用任何能为文件内容添加语法高亮的程序,例如 Bat 或 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)。
更多进阶示例请参见此处。
警告
由于 fzf 是通用文本过滤器,而不是文件查找器,不建议将
--preview选项添加到你的$FZF_DEFAULT_OPTS中。# ********************* # ** DO NOT DO THIS! ** # ********************* export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"' # bat doesn't work with any input other than the list of files ps -ef | fzf seq 100 | fzf history | fzf
预览图像
fzf 可以使用以下协议之一在预览窗口中显示图像:
更多信息请参阅 bin/fzf-preview.sh 脚本。
fzf --preview 'fzf-preview.sh {}'
技巧
遵循 .gitignore
你可以使用 fd、
ripgrep 或 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 按键绑定会将命令行中的最后一个词元用作递归搜索的根目录。例如,在以下命令行末尾按下 CTRL-T:
ls /var/
会列出 /var/ 下的所有文件和目录。
使用自定义 FZF_CTRL_T_COMMAND 时,请使用未展开的 $dir 变量来利用此功能。如果最后一个词元不是有效目录,$dir 默认为 .。示例:
set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"
fzf 主题试验场
由 Vitor Mello 创建的 fzf 主题试验场 是一个可供你交互式创建 fzf 主题的网页。
相关项目
https://github.com/junegunn/fzf/wiki/Related-projects
许可证
MIT 许可证(MIT)
版权所有 (c) 2013-2026 Junegunn Choi
周边商品
在这里购买 fzf T 恤、马克杯和贴纸:commitgoods.com/collections/fzf
赞助者 :heart:
我想感谢本项目的所有赞助者,正是你们让我能够继续改进 fzf。
如果你想赞助本项目,请访问 https://github.com/sponsors/junegunn。


