项目文件夹

文件
2026-07-13 09:50:27 +00:00

1078 行
40 KiB
Markdown

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
<!-- 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.