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

1078 lines
40 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- WEHUB_ZH_README -->
> [!NOTE]
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
> [English](./README.en.md) · [原始项目](https://github.com/junegunn/fzf) · [上游 README](https://github.com/junegunn/fzf/blob/HEAD/README.md)
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
<div align="center">
<img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-color.png" alt="fzf - 命令行模糊查找器">
<a href="https://github.com/junegunn/fzf/actions"><img src="https://github.com/junegunn/fzf/actions/workflows/linux.yml/badge.svg?branch=master" alt="构建状态"></a>
<a href="http://github.com/junegunn/fzf/releases"><img src="https://img.shields.io/github/v/tag/junegunn/fzf" alt="版本"></a>
<a href="https://github.com/junegunn/fzf?tab=MIT-1-ov-file#readme"><img src="https://img.shields.io/github/license/junegunn/fzf" alt="许可证"></a>
<a href="https://github.com/junegunn/fzf/graphs/contributors"><img src="https://img.shields.io/github/contributors/junegunn/fzf" alt="贡献者"></a>
<a href="https://github.com/sponsors/junegunn"><img src="https://img.shields.io/github/sponsors/junegunn" alt="赞助者"></a>
<a href="https://github.com/junegunn/fzf/stargazers"><img src="https://img.shields.io/github/stars/junegunn/fzf?style=flat" alt="星标"></a>
</div>
---
<kbd align="center">
<br/>
<a href="https://commitgoods.com/collections/fzf"><img src="https://junegunn.github.io/fzf/images/fzf-mugs.jpg" width="80%" alt="fzf 周边"></a>
<br/>
<br/>
表达对 fzf 的喜爱——T 恤、马克杯和贴纸现已上架!
<br/>
<br/>
<a href="https://commitgoods.com/collections/fzf">commitgoods.com/collections/fzf</a>
<br/>
<br/>
</kbd>
---
fzf 是一款通用命令行模糊查找器(fuzzy finder)和交互式终端工具包。
<img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-preview.png" width=640>
无论你是选择文件、浏览命令历史、预览数据、
通过模糊匹配浏览复杂数据集,还是创建自定义菜单和
工作流,fzf 都提供了将 shell 脚本转变为丰富
终端应用所需的构建模块。
亮点
----------
- **便携** // 以单一二进制文件分发,便于安装
- **快速** // 经过优化,可在毫秒内处理数百万条目
- **可编程** // 事件驱动架构,用于构建自定义终端界面和工作流
- **开箱即用** // 内置与 Bash、Zsh、Fish、Nushell、Vim 和 Neovim 的集成
目录
-----------------
<!-- vim-markdown-toc GFM -->
* [安装](#installation)
* [使用 Homebrew](#using-homebrew)
* [使用 Mise](#using-mise)
* [Linux 软件包](#linux-packages)
* [Windows 软件包](#windows-packages)
* [使用 git](#using-git)
* [二进制发行版](#binary-releases)
* [配置 shell 集成](#setting-up-shell-integration)
* [Vim/Neovim 插件](#vimneovim-plugin)
* [升级 fzf](#upgrading-fzf)
* [构建 fzf](#building-fzf)
* [用法](#usage)
* [使用查找器](#using-the-finder)
* [显示模式](#display-modes)
* [`--height` 模式](#--height-mode)
* [`--popup` 模式](#--popup-mode)
* [搜索语法](#search-syntax)
* [环境变量](#environment-variables)
* [自定义外观](#customizing-the-look)
* [选项](#options)
* [演示](#demo)
* [示例](#examples)
* [命令行快捷键](#key-bindings-for-command-line)
* [模糊补全](#fuzzy-completion)
* [文件和目录](#files-and-directories)
* [进程 ID](#process-ids)
* [主机名](#host-names)
* [环境变量 / 别名](#environment-variables--aliases)
* [为 bash 和 zsh 自定义模糊补全](#customizing-fuzzy-completion-for-bash-and-zsh)
* [自定义 fzf 补全选项](#customizing-fzf-options-for-completion)
* [自定义路径和目录的补全来源](#customizing-completion-source-for-paths-and-directories)
* [支持的命令(bash](#supported-commands-bash)
* [自定义模糊补全](#custom-fuzzy-completion)
* [Fish 的模糊补全](#fuzzy-completion-for-fish)
* [Nushell 的模糊补全](#fuzzy-completion-for-nushell)
* [Vim 插件](#vim-plugin)
* [高级主题](#advanced-topics)
* [针对不同输入类型的自定义](#customizing-for-different-types-of-input)
* [性能](#performance)
* [执行外部程序](#executing-external-programs)
* [切换为不同进程](#turning-into-a-different-process)
* [重新加载候选列表](#reloading-the-candidate-list)
* [1. 按 CTRL-R 更新进程列表](#1-update-the-list-of-processes-by-pressing-ctrl-r)
* [2. 按 CTRL-D 或 CTRL-F 在来源之间切换](#2-switch-between-sources-by-pressing-ctrl-d-or-ctrl-f)
* [3. 交互式 ripgrep 集成](#3-interactive-ripgrep-integration)
* [预览窗口](#preview-window)
* [预览图片](#previewing-an-image)
* [技巧](#tips)
* [遵循 `.gitignore`](#respecting-gitignore)
* [Fish shell](#fish-shell)
* [fzf 主题游乐场](#fzf-theme-playground)
* [相关项目](#related-projects)
* [许可证](#license)
* [周边商品](#goods)
* [赞助者 :heart:](#sponsors-heart)
<!-- vim-markdown-toc -->
安装
------------
### 使用 Homebrew
你可以使用 [Homebrew](https://brew.sh/)(在 macOS 或 Linux 上)安装 fzf。
```sh
brew install fzf
```
> [!IMPORTANT]
> 要配置 shell 集成(快捷键和模糊补全),
> 请参阅[下方说明](#setting-up-shell-integration)。
fzf 也可通过 [MacPorts][portfile] 获取:`sudo port install fzf`
[portfile]: https://github.com/macports/macports-ports/blob/master/sysutils/fzf/Portfile
### 使用 Mise
你可以使用 [mise](https://github.com/jdx/mise) 安装 fzf。
```sh
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 集成(快捷键和模糊补全),
> 请参阅[下方说明](#setting-up-shell-integration)。
[![Packaging status](https://repology.org/badge/vertical-allrepos/fzf.svg?columns=3)](https://repology.org/project/fzf/versions)
### Windows 软件包
在 Windows 上,可通过 [Chocolatey][choco]、[Scoop][scoop]、
[Winget][winget] 和 [MSYS2][msys2] 安装 fzf
| 软件包管理器 | 命令 |
| --------------- | ------------------------------------- |
| Chocolatey | `choco install fzf` |
| Scoop | `scoop install fzf` |
| Winget | `winget install fzf` |
| MSYS2 (pacman) | `pacman -S $MINGW_PACKAGE_PREFIX-fzf` |
[choco]: https://chocolatey.org/packages/fzf
[scoop]: https://github.com/ScoopInstaller/Main/blob/master/bucket/fzf.json
[winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/j/junegunn/fzf
[msys2]: https://packages.msys2.org/base/mingw-w64-fzf
### 使用 git
或者,你可以将此仓库 "git clone" 到任意目录,然后运行
[安装](https://github.com/junegunn/fzf/blob/master/install) 脚本。
```sh
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
```
安装脚本会向你的 shell 配置文件中添加行,以修改
`$PATH` 并设置 shell 集成。
### 二进制发布版
你可以从发布页面下载官方的 fzf 二进制文件。
* https://github.com/junegunn/fzf/releases
### 设置 shell 集成
将以下行添加到你的 shell 配置文件中。
* bash
```sh
# 设置 fzf 快捷键和模糊补全
eval "$(fzf --bash)"
```
* zsh
```sh
# 设置 fzf 快捷键和模糊补全
source <(fzf --zsh)
```
* fish
```fish
# 设置 fzf 快捷键
fzf --fish | source
```
* Nushell——Nushell 不支持将内容管道到 `source`,因此安装
脚本会在自动加载目录中生成一个文件。如果你没有使用安装脚本,可以手动设置:
```nu
# 生成集成脚本
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](/shell) 目录中的各个脚本文件。这些
> 文件的位置可能因你所用的包管理器而异。
> 请参阅包文档以获取更多信息。
> (例如 `apt show fzf`
> [!TIP]
> 你可以通过在引用脚本时,将对应的 `*_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](https://github.com/junegunn/vim-plug),),请将以下内容添加到
你的 Vim 配置文件中:
```vim
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
```
* `junegunn/fzf` 提供基础库函数
* `fzf#install()` 确保你拥有最新二进制文件
* `junegunn/fzf.vim` 是[一个独立项目](https://github.com/junegunn/fzf.vim))
提供各种有用的命令
要了解更多关于 Vim 集成的信息,请参阅 [README-VIM.md](README-VIM.md)。
> [!TIP]
> 如果你使用 Neovim 并偏好基于 Lua 的插件,请查看
> [fzf-lua](https://github.com/ibhagwan/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](BUILD.md)。
用法
-----
fzf 会启动交互式查找器,从 STDIN 读取列表,并将选中的项目写入 STDOUT。
```sh
find * -type f | fzf > selected
```
没有 STDIN 管道时,fzf 会遍历当前目录下的文件系统来获取文件列表。
```sh
vim $(fzf)
```
> [!NOTE]
> 你可以覆盖默认行为
> * 要么将 `$FZF_DEFAULT_COMMAND` 设置为一个生成所需列表的命令
> * 要么在 `$FZF_DEFAULT_OPTS` 中设置 `--walker`、`--walker-root` 和 `--walker-skip` 选项
> [!WARNING]
> 更稳健的解决方案是使用 `xargs`,但我们展示
> 了上述方案,因为它更容易理解
> ```sh
> fzf --print0 | xargs -0 -o vim
> ```
> [!TIP]
> fzf 还能够将自身转换为另一个进程。
>
> ```sh
> fzf --bind 'enter:become(vim {})'
> ```
>
> *有关更多信息,请参阅[转换为另一个进程](#turning-into-a-different-process)。*
### 使用查找器
- `CTRL-K` / `CTRL-J`(或 `CTRL-P` / `CTRL-N`)上下移动光标
- `Enter` 键选择项目,`CTRL-C` / `CTRL-G` / `ESC` 退出
- 多选模式(`-m`)下,使用 `TAB` 和 `Shift-TAB` 标记多个项目
- Emacs 风格快捷键
- 鼠标:滚动、单击、双击;多选模式下 shift+单击 和 shift+滚动
### 显示模式
fzf 默认以全屏模式运行,但也有其他显示模式。
#### `--height` 模式
使用 `--height HEIGHT[%]`,fzf 将在光标下方以指定高度启动。
```sh
fzf --height 40%
```
`reverse` 布局和 `--border` 与此选项搭配效果良好。
```sh
fzf --height 40% --layout reverse --border
```
在高度前加上 `~`,可以设置最大高度。
```sh
# Will take as few lines as possible to display the list
seq 3 | fzf --height ~100%
seq 3000 | fzf --height ~100%
```
高度值可以是负数。
```sh
# Screen height - 3
fzf --height -3
```
#### `--popup` 模式
使用 `--popup` 选项,fzf 将在弹出窗口中启动
(需要 tmux 3.3+ 或 Zellij 0.44+)。
```sh
# --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](bin/fzf-tmux) 脚本。
> [!TIP]
> 你可以将这些选项添加到 `$FZF_DEFAULT_OPTS` 中,以便默认应用它们。
> 例如,
>
> ```sh
> # 如果在 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` 开头
且以 `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`
> [!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 的用户界面可通过大量配置选项进行完全自定义。如需快速设置,你可以使用 `default`、`full` 或 `minimal` 等样式预设之一,通过 `--style` 选项启动。
```sh
fzf --style full \
--preview 'fzf-preview.sh {}' --bind 'focus:transform-header:file --brief {}'
```
| 预设 | 截图 |
| :--- | :--- |
| `default` | <img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-style-default.png"/> |
| `full` | <img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-style-full.png"/> |
| `minimal` | <img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-style-minimal.png"/> |
以下是一个基于 `full` 预设的示例:
<img src="https://raw.githubusercontent.com/junegunn/i/master/fzf-4-borders.png"/>
<details>
```sh
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'
```
</details>
### 选项
请查阅手册(`fzf --man` 或 `man fzf`)获取完整选项列表。
### 演示
如果你喜欢通过视频学习,可以观看 [@samoshkin](https://github.com/samoshkin)) 制作的这个录屏,探索 `fzf` 的各项功能。
<a title="fzf - 命令行模糊查找器" href="https://www.youtube.com/watch?v=qgG5Jhi_Els">
<img src="https://i.imgur.com/vtG8olE.png" width="640">
</a>
示例
--------
* [示例 Wiki 页面](https://github.com/junegunn/fzf/wiki/examples))
* *免责声明:该页面上的示例由社区维护,未经全面测试*
* [高级 fzf 示例](https://github.com/junegunn/fzf/blob/master/ADVANCED.md))
命令行按键绑定
-----------------------------
通过[设置 shell 集成](#setting-up-shell-integration),你可以在 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 传递额外选项
```sh
# 使用 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 传递额外选项
```sh
# 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
# 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 传递额外选项
```sh
# 在预览窗口中打印树形结构
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 页面](https://github.com/junegunn/fzf/wiki/Configuring-shell-key-bindings).)
模糊补全
----------------
Shell 集成还为 bash、zsh、fish 和 Nushell 提供了模糊补全功能。
### 文件和目录
如果光标前的单词以触发序列结尾(默认为 `**`),则可触发文件和目录的模糊补全。
- `COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TAB>`
```sh
# 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 的模糊补全。
```sh
# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 **<TAB>
```
### 主机名
为 ssh 命令提供了主机名的模糊补全。主机名从 /etc/hosts 和 ~/.ssh/config 中提取。
```sh
ssh **<TAB>
```
### 环境变量 / 别名
```sh
# bash and zsh
unset **<TAB>
export **<TAB>
unalias **<TAB>
# fish
set <SHIFT-TAB>
```
### 自定义 bash 和 zsh 的模糊补全
#### 自定义补全的 fzf 选项
```sh
# 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
}
```
#### 自定义路径和目录的补全来源
```sh
# 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`` 辅助函数为其他命令启用模糊补全。
```sh
# 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`` 函数。
```sh
# 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`` 命令手动将函数与命令关联。
```sh
[ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge
```
如果你需要对 fzf 的输出进行后处理,可以按如下方式定义
``_fzf_complete_COMMAND_post``。
```sh
_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 补全函数:
```fish
# 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 的输出进行处理后再插入命令行:
```fish
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 中的模糊补全通过
[外部补全器](https://www.nushell.sh/cookbook/external_completers.html))
机制实现。与 bash 和 zsh 相比存在一些差异:
- 在 Nushell >= 0.103.0 上,内置命令(例如 ``cd``、``ls``)不再调用外部补全器。使用 ``**<TAB>`` 的模糊补全仅对外部命令生效。
- 自定义补全器可以通过 ``$env.FZF_COMPLETERS`` 记录在你的
``config.nu`` 中定义。每个条目是一个闭包,接收前缀和命令跨度,返回候选字符串列表或包含自定义 fzf 选项的记录
``{ candidates: [...], opts: [...] }``
```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 {}"] }
}
}
```
更多示例请参见 [shell/completion-examples.nu](shell/completion-examples.nu)。
- 支持以下环境变量:
``FZF_COMPLETION_TRIGGER``、``FZF_COMPLETION_OPTS``、
``FZF_COMPLETION_PATH_OPTS``、``FZF_COMPLETION_DIR_OPTS``、
``FZF_COMPLETION_DIR_COMMANDS``。
Vim 插件
----------
参见 [README-VIM.md](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 的情况下启动外部进程(``execute``、``execute-silent``)。
````bash
# 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 切换为执行该命令的新进程。
````sh
fzf --bind 'enter:become(vim {})'
````
与看似等效的命令替换 ``vim "$(fzf)"`` 相比,这种方式有几个优势:
* 当用 <kbd>CTRL-C</kbd> 终止 fzf 时,Vim 不会打开空文件
* 当在空结果上按 <kbd>ENTER</kbd> 时,Vim 不会打开空文件
* 可以处理多项选择,即使其中包含空格
```sh
fzf --multi --bind 'enter:become(vim {+})'
```
公平地说,使用 ``fzf --print0 | xargs -0 -o vim`` 代替 ``vim "$(fzf)"`` 可以解决上述所有问题。尽管如此,``become(...)`` 在不同场景下仍提供了额外优势。
* 你可以设置多个绑定,以不同方式处理结果,而无需任何包装脚本
```sh
fzf --bind 'enter:become(vim {}),ctrl-e:become(emacs {})'
```
* 之前,你需要使用 ``--expect=ctrl-e`` 并检查 fzf 输出的第一行
* 你可以利用 fzf 的字段索引表达式轻松构建后续命令
```sh
# 在 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 更新进程列表
````sh
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 切换源
````sh
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 不执行任何二次过滤。
````sh
: | 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"](`https://github.com/junegunn/fzf/blob/master/ADVANCED.md#using-fzf-as-interactive-ripgrep-launcher)`)。
### 预览窗口
设置 ``--preview`` 选项后,fzf 会自动启动一个外部进程,将当前行作为参数传入,并在拆分窗口中显示结果。你的 ``$SHELL`` 用于执行该命令,``$SHELL -c COMMAND`` 作为参数传入。可以使用鼠标或自定义按键绑定来滚动窗口。
````bash
# {} is replaced with the single-quoted string of the focused line
fzf --preview 'cat {}'
````
预览窗口支持 ANSI 颜色,因此你可以使用任何能够对文件内容进行语法高亮的程序,例如 [Bat](`https://github.com/sharkdp/bat)`) 或 [Highlight](`https://gitlab.com/saalen/highlight):`)。
````bash
fzf --preview 'bat --color=always {}' --preview-window '~3'
````
你可以使用 ``--preview-window`` 选项自定义预览窗口的大小、位置和边框,使用 ``--color`` 选项自定义其前景色和背景色。例如:
````bash
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``)。
更多高级示例请参见[此处](`https://github.com/junegunn/fzf/blob/master/ADVANCED.md).`)。
> [!WARNING]
> 由于 fzf 是通用文本过滤器而非文件查找器,**不建议将 ``--preview`` 选项加入你的 ``$FZF_DEFAULT_OPTS``**。
>
> ```sh
> # *********************
> # ** 不要这样做!**
> # *********************
> export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"'
>
> # bat 不适用于除文件列表以外的任何输入
> ps -ef | fzf
> seq 100 | fzf
> history | fzf
> ```
### 预览图片
fzf 可以通过以下协议之一在预览窗口中显示图片:
* [Kitty 图形协议](`https://sw.kovidgoyal.net/kitty/graphics-protocol/)`)
* [iTerm2 内联图片协议](`https://iterm2.com/documentation-images.html)`)
* [Sixel](`https://en.wikipedia.org/wiki/Sixel)`)
更多信息请参见 [bin/fzf-preview.sh](bin/fzf-preview.sh) 脚本。
````sh
fzf --preview 'fzf-preview.sh {}'
````
技巧
----
### 遵守 ``.gitignore``
你可以使用 [fd](`https://github.com/sharkdp/fd),`)、[ripgrep](`https://github.com/BurntSushi/ripgrep),`) 或 [The Silver Searcher](`https://github.com/ggreer/the_silver_searcher)`) 来遍历文件系统,同时遵守 ``.gitignore``。
````sh
# 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"
````
如果你希望命令跟随符号链接且不排除隐藏文件,请使用以下命令:
````sh
export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git'
````
### Fish shell
与 bash 和 zsh 不同,fish 的 ``CTRL-T`` 按键绑定会将命令行上的最后一个 token 作为递归搜索的根目录。例如,在以下命令行的末尾按下 ``CTRL-T``
````sh
ls /var/
````
将列出 ``/var/`` 下的所有文件和目录。
使用自定义 ``FZF_CTRL_T_COMMAND`` 时,请使用未展开的 ``$dir`` 变量来利用此功能。当最后一个 token 不是有效目录时,``$dir`` 默认为 ``.``。示例:
````sh
set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"
````
### fzf 主题游乐场
[fzf 主题游乐场](`https://vitormv.github.io/fzf-themes/)`) 由 [Vitor Mello](`https://github.com/vitormv)`) 创建,是一个可以交互式创建 fzf 主题的网页。
相关项目
--------
`https://github.com/junegunn/fzf/wiki/Related-projects`
[License](LICENSE)
------------------
MIT 许可证 (MIT)
Copyright (c) 2013-2026 Junegunn Choi
Goods
-----
在此获取 fzf T 恤、马克杯和贴纸:https://commitgoods.com/collections/fzf
Sponsors :heart:
----------------
我要感谢本项目的所有赞助商,是他们让我能够继续改进 fzf。
如果你想赞助本项目,请访问 https://github.com/sponsors/junegunn.