junegunn/fzf

GitHub: junegunn/fzf

一款用 Go 编写的通用命令行模糊查找器,通过智能模糊匹配和丰富的 Shell 集成,帮助用户在海量文件、命令历史和各类列表中快速定位目标。

Stars: 78629 | Forks: 2721

fzf - a command-line fuzzy finder Build Status Version License Contributors Sponsors Stars
fzf 是一个通用的命令行模糊查找器。 它是一个适用于任何类型列表的交互式过滤程序;文件、命令历史、进程、主机名、书签、git commits 等。它实现了一个“模糊”匹配算法,因此你可以快速输入带有遗漏字符的模式,并且仍然获得你想要的结果。 ## 亮点 - **可移植** — 以单一二进制文件分发,便于安装 - **极速** — 经过优化,可瞬间处理数百万个项目 - **通用** — 通过事件-动作绑定机制完全可定制 - **全能** — 自带 Bash, Zsh, Fish, Vim, 和 Neovim 集成 ## 目录 * [安装](#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) * [`--tmux` 模式](#--tmux-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) * [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) ## 安装 ### 使用 Homebrew 你可以使用 [Homebrew](https://brew.sh/) (在 macOS 或 Linux 上)来安装 fzf。 ``` brew install fzf ``` fzf 也可以 [通过 MacPorts 安装][portfile]:`sudo port install fzf` ### 使用 Mise 你可以使用 [mise](https://github.com/jdx/mise) 来安装 fzf。 ``` mise use -g fzf@latest ``` ### Linux 软件包 | Package Manager | Linux Distribution | Command | | --------------- | ----------------------- | ---------------------------------- | | 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` | [![Packaging status](https://repology.org/badge/vertical-allrepos/fzf.svg?columns=3)](https://repology.org/project/fzf/versions) ### Windows 软件包 在 Windows 上,fzf 可通过 [Chocolatey][choco]、[Scoop][scoop]、[Winget][winget] 和 [MSYS2][msys2] 获取: | Package manager | Command | | --------------- | ------------------------------------- | | Chocolatey | `choco install fzf` | | Scoop | `scoop install fzf` | | Winget | `winget install fzf` | | MSYS2 (pacman) | `pacman -S $MINGW_PACKAGE_PREFIX-fzf` | ### 使用 git 或者,你可以将此仓库 “git clone” 到任何目录并运行 [install](https://github.com/junegunn/fzf/blob/master/install) 脚本。 ``` 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 # 设置 fzf 按键绑定和模糊补全 eval "$(fzf --bash)" * zsh # 设置 fzf 按键绑定和模糊补全 source <(fzf --zsh) * fish # 设置 fzf 按键绑定 fzf --fish | source ### Vim/Neovim 插件 如果你使用 [vim-plug](https://github.com/junegunn/vim-plug),请将此添加到你的 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)。 ## 升级 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。 ``` find * -type f | fzf > selected ``` 如果没有 STDIN 管道,fzf 将遍历当前目录下的文件系统以获取文件列表。 ``` vim $(fzf) ``` ### 使用查找器 - `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 将在光标下方以给定的高度启动。 ``` fzf --height 40% ``` `reverse` 布局和 `--border` 与此选项配合良好。 ``` fzf --height 40% --layout reverse --border ``` 通过在高度前添加 `~`,你设置的是最大高度。 ``` # 将以尽可能少的行数显示列表 seq 3 | fzf --height ~100% seq 3000 | fzf --height ~100% ``` 高度值可以是一个负数。 ``` # 屏幕高度 - 3 fzf --height -3 ``` #### `--tmux` 模式 使用 `--tmux` 选项,fzf 将在 tmux 弹出窗口中启动。 ``` # --tmux [center|top|bottom|left|right][,SIZE[%]][,SIZE[%][,border-native]] fzf --tmux center # Center, 50% width and height fzf --tmux 80% # Center, 80% width and height fzf --tmux 100%,50% # Center, 100% width and 50% height fzf --tmux left,40% # Left, 40% width fzf --tmux left,40%,90% # Left, 40% width, 90% height fzf --tmux top,40% # Top, 40% height fzf --tmux bottom,80%,40% # Bottom, 80% width, 40% height ``` 当你不在 tmux 中时,`--tmux` 会被静默忽略。 ### 搜索语法 除非另有说明,fzf 在“扩展搜索模式”下启动,你可以在其中输入由空格分隔的多个搜索词。例如:`^music .mp3$ sbtrkt !fire` | Token | Match type | Description | | --------- | -------------------------------------- | ------------------------------------------ | | `sbtrkt` | fuzzy-match | Items that match `sbtrkt` | | `'wild` | exact-match (quoted) | Items that include `wild` | | `'wild'` | exact-boundary-match (quoted both ends) | Items that include `wild` at word boundaries | | `^music` | prefix-exact-match | Items that start with `music` | | `.mp3$` | suffix-exact-match | Items that end with `.mp3` | | `!fire` | inverse-exact-match | Items that do not include `fire` | | `!^music` | inverse-prefix-exact-match | Items that do not start with `music` | | `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.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` ### 自定义外观 fzf 的用户界面可以通过大量配置选项完全自定义。为了快速设置,你可以使用 `--style` 选项从预设样式(`default`、`full` 或 `minimal`)中选择一个开始。 ``` fzf --style full \ --preview 'fzf-preview.sh {}' --bind 'focus:transform-header:file --brief {}' ``` | Preset | Screenshot | | :--- | :--- | | `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 page (`fzf --man` 或 `man fzf`) 获取完整的选项列表。 ### 演示 如果你通过观看视频学习,请查看 [@samoshkin](https://github.com/samoshkin) 的此录屏以探索 `fzf` 功能。 ## 示例 * [示例 Wiki 页面](https://github.com/junegunn/fzf/wiki/examples) * *免责声明:此页面上的示例由社区维护,并未经过彻底测试* * [高级 fzf 示例]() ## 命令行快捷键绑定 通过[设置 shell 集成](#setting-up-shell-integration),你可以在 bash、zsh 和 fish 中使用以下快捷键绑定。 - `CTRL-T` - 将选定的文件和目录粘贴到命令行 - 列表是使用 `--walker file,dir,follow,hidden` 选项生成的 - 你可以通过将 `FZF_CTRL_T_COMMAND` 设置为生成所需列表的自定义命令来覆盖该行为 - 或者你可以在 `FZF_CTRL_T_OPTS` 中设置 `--walker*` 选项 - 设置 `FZF_CTRL_T_OPTS` 以将附加选项传递给 fzf # 使用 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` - 将从历史记录中选择的命令粘贴到命令行 - 如果你想按时间顺序查看命令,请再次按 `CTRL-R`,这会切换按相关性排序 - 按 `ALT-R` 切换“原始”模式,在该模式下你可以看到匹配项周围的项目。在此模式下,你可以按 `CTRL-N` 和 `CTRL-P` 仅在匹配项目之间移动。 - 按 `CTRL-/` 或 `ALT-/` 切换换行 - 设置 `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'" - 可以在执行脚本时通过将 `FZF_CTRL_R_COMMAND` 设置为空字符串来禁用 - 尚不支持通过非空的 `FZF_CTRL_R_COMMAND` 进行自定义覆盖,这将发出警告 - `ALT-C` - cd 进入选定的目录 - 列表是使用 `--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='--tmux bottom,60% --height 60% --border top'`) 更多技巧可以在 [wiki 页面](https://github.com/junegunn/fzf/wiki/Configuring-shell-key-bindings) 上找到。 ## 模糊补全 Shell 集成还为 bash、zsh 和 fish 提供了模糊补全功能。 ### 文件和目录 如果光标前的单词以触发序列(默认为 `**`)结尾,则可以触发文件和目录的模糊补全。 - `COMMAND [DIRECTORY/][FUZZY_PATTERN]**` ``` # 当前目录下的文件 # - 您可以使用 TAB 键选择多个项目 vim ** # 父目录下的文件 vim ../** # 父目录下匹配 `fzf` 的文件 vim ../fzf** # 您主目录下的文件 vim ~/** # 当前目录下的目录(单选) cd ** # ~/github 下匹配 `fzf` 的目录 cd ~/github/fzf** ``` ### 进程 ID kill 命令提供了 PIDs 的模糊补全。 ``` # 可以使用 键选择多个进程 kill -9 ** ``` ### 主机名 对于 ssh 命令,提供了主机名的模糊补全。名称从 /etc/hosts 和 ~/.ssh/config 中提取。 ``` ssh ** ``` ### 环境变量 / 别名 ``` # bash 和 zsh unset ** export ** unalias ** # fish set ``` ### 为 bash 和 zsh 自定义模糊补全 #### 为补全自定义 fzf 选项 ``` # 使用 ~~ 作为触发序列,而不是默认的 ** export FZF_COMPLETION_TRIGGER='~~' # fzf 命令的选项 export FZF_COMPLETION_OPTS='--border --info=inline' # 路径补全选项(例如 vim **) export FZF_COMPLETION_PATH_OPTS='--walker file,dir,follow,hidden' # 目录补全选项(例如 cd **) export FZF_COMPLETION_DIR_OPTS='--walker dir,follow' # 通过 _fzf_comprun 函数高级自定义 fzf 选项 # - 传递给函数的第一个参数是命令的名称。 # - 您应该确保将其余参数 ($@) 传递给 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 } ``` #### 为路径和目录自定义补全源 ``` # 使用 fd 列出路径候选。 # - 传递给函数的第一个参数 ($1) 是开始遍历的基路径 # - 详情请参阅源代码。 _fzf_compgen_path() { fd --hidden --follow --exclude ".git" . "$1" } # 使用 fd 生成目录补全列表 _fzf_compgen_dir() { fd --type d --hidden --follow --exclude ".git" . "$1" } ``` #### 支持的命令 (bash) 在 bash 上,仅为一组预定义的命令启用模糊补全(运行 `complete | grep _fzf` 查看列表)。但你也可以使用 `_fzf_setup_completion` 辅助函数为其他命令启用它。 ``` # 用法: _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` 函数。 ``` # "doge" 命令的自定义模糊补全 # 例如 doge ** _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 的模糊补全 (在 0.68.0 或更高版本中可用) fish 的模糊补全与 bash 和 zsh 的不同之处在于: - 它不需要像 `**` 这样的触发序列。相反,它在 `Shift-TAB` 上激活,而 `TAB` 保留 fish 的原生补全行为。 - 它依赖 fish 的原生补全系统来填充候选列表,而不是执行递归文件系统遍历。对于递归搜索,请改用 `CTRL-T` 绑定。 - 唯一支持的配置变量是 `FZF_COMPLETION_OPTS`。 也就是说,就像在 bash 和 zsh 中一样,你可以通过定义 `_fzf_complete_COMMAND` 函数来为特定命令实现自定义补全。例如: ``` function _fzf_complete_foo function _fzf_complete_foo_post awk '{print $NF}' end _fzf_complete --multi --reverse --header-lines=3 -- $argv < (ls -al | psub) functions -e _fzf_complete_foo_post end ``` 这里有一个更复杂的自定义 `git` 的示例 ``` function _fzf_complete_git switch $argv[2] case checkout switch _fzf_complete --reverse --no-preview -- $argv < (git branch --all --format='%(refname:short)' | psub) case add function _fzf_complete_git_post awk '{print $NF}' end _fzf_complete --multi --reverse -- $argv < (git status --short | psub) case show log diff function _fzf_complete_git_post awk '{print $1}' end _fzf_complete --reverse --no-sort --preview='git show --color=always {1}' -- $argv < (git log --oneline | psub) case '' __fzf_complete_native "$argv[1] " --query=(commandline -t | string escape) case '*' set -l -- current_token (commandline -t) __fzf_complete_native "$argv $current_token" --query=(string escape -- $current_token) --multi end functions -e _fzf_complete_git_post end ``` ## Vim 插件 参见 [README-VIM.md](README-VIM.md)。 ## 高级主题 ### 针对不同类型的输入进行自定义 由于 fzf 是一个通用的文本过滤器,其算法设计旨在“通常”适用于任何类型的输入。然而,诚然,没有真正的万全之策,你可能希望根据输入类型调整算法和一些设置。为了简化此过程,fzf 为一些常见的输入类型提供了一组“方案”。 | Scheme | Description | | :--- | :--- | | `--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`)。 ``` # 按 F1 使用 less 打开文件而不离开 fzf # 按 CTRL-Y 将该行复制到剪贴板并退出 fzf (需要 pbcopy) fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort' ``` 有关详细信息,请参见 man page 的 *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 的字段索引表达式轻松构建后续命令 # 在 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”](https://github.com/junegunn/fzf/blob/master/ADVANCED.md#using-fzf-as-interactive-ripgrep-launcher) 获取更复杂的示例。 ### 预览窗口 当设置了 `--preview` 选项时,fzf 会自动启动一个外部进程,将当前行作为参数,并在拆分窗口中显示结果。你的 `$SHELL` 用于执行带有 `$SHELL -c COMMAND` 的命令。 该窗口可以使用鼠标或自定义键绑定进行滚动。 ``` # {} 会被替换为焦点行的单引号字符串 fzf --preview 'cat {}' ``` 预览窗口支持 ANSI 颜色,因此你可以使用任何对文件内容进行语法高亮的程序,例如 [Bat](https://github.com/sharkdp/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 page (`man fzf`)。 更多高级示例可以在[这里](https://github.com/junegunn/fzf/blob/master/ADVANCED.md)找到。 ### 预览图片 fzf 可以使用以下协议之一在预览窗口中显示图片: * [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) * [iTerm2 inline images protocol](https://iterm2.com/documentation-images.html) * [Sixel](https://en.wikipedia.org/wiki/Sixel) 有关更多信息,请参见 [bin/fzf-preview.sh](bin/fzf-preview.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`。 ``` # 将 fd 的输出通过管道传输给 fzf fd --type f --strip-cwd-prefix | fzf # 将 fd 设置为 fzf 的默认源 export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix' # 现在 fzf (无管道) 将使用 fd 命令来生成列表 fzf # 同时也将命令应用于 CTRL-T 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](https://github.com/vitormv) 创建的 [fzf Theme Playground](https://vitormv.github.io/fzf-themes/) 是一个网页,你可以在其中交互式地创建 fzf 主题。 ## 相关项目 https://github.com/junegunn/fzf/wiki/Related-projects ## [许可证](LICENSE) The MIT License (MIT) Copyright (c) 2013-2026 Junegunn Choi ## 周边商品 在这里获取 fzf T 恤、马克杯和贴纸:https://commitgoods.com/collections/fzf ## 赞助者 :heart: 我要感谢这个项目的所有赞助者,是他们使我能够继续改进zf。 如果你想赞助这个项目,请访问 https://github.com/sponsors/junegunn。 User avatar: miyanokomiyaUser avatar: Kyle L. DavisUser avatar: Frederick ZhangUser avatar: Moritz DietzUser avatar: Pierre DubouilhUser avatar: Fulvio ScapinUser avatar: Ryan Roden-CorrentUser avatar: Jordan ArentsenUser avatar: Alex ViscreanuUser avatar: User avatar: Ben ElanUser avatar: Paweł Kolonko-DudaUser avatar: M KellyUser avatar: ArtBITUser avatar: HovisUser avatar: Chang-Hung LiangUser avatar: Ben LechlitnerUser avatar: Takumi KAGIYAMAUser avatar: Paul OLeary McCannUser avatar: Robert BeegerUser avatar: Josh ScalisiUser avatar: Alec ScottUser avatar: Artur SapekUser avatar: Guillaume GelinUser avatar: User avatar: Rob LevyUser avatar: Markus KollerUser avatar: User avatar: jamesobUser avatar: Johan Le BrayUser avatar: Panos LampropoulosUser avatar: bespinianUser avatar: Markus Schneider-PargmannUser avatar: Charlie EganUser avatar: Tyler HobbsUser avatar: Neil ParikhUser avatar: dockienUser avatar: Russell GilmoreUser avatar: Lukas WaymannUser avatar: Farzad SadeghiUser avatar: User avatar: Bruno PazUser avatar: Timothy BennettUser avatar: Daniel HornerUser avatar: Red OchsenbeinUser avatar: YuryUser avatar: User avatar: Chris G.User avatar: Lou ZellUser avatar: FabioUser avatar: Justin LubinUser avatar: Kevin TodayUser avatar: CokoUser avatar: Joel BUser avatar: Fabrizio DamicelliUser avatar: SonamiUser avatar: Jan-Kåre SolbakkenUser avatar: Trash NothingUser avatar: User avatar: Jakub Piotr CłapaUser avatar: DANIII3LUser avatar: HestUser avatar: User avatar: guttermonkUser avatar: User avatar: Håvard MoenUser avatar: Haoyu YANG 杨浩宇User avatar: Gang Li
标签:Awesome, Bash, DNS解析, EVTX分析, Fish, Git集成, Go语言, Linux软件, Neovim, Shell集成, TUI, Vim, Zsh, 交互式过滤器, 历史记录搜索, 命令行界面, 威胁情报, 应用安全, 开发者工具, 开源项目, 搜索算法, 效率提升, 文件搜索, 文本处理, 日志审计, 模糊查找, 程序破解, 系统管理, 终端实用程序