技术解析

fzf-tab - 使用 fzf 作为 zsh 的补全选择菜单
0
2021-06-17 16:54:21
idczone

简介

fzf-tab 是一个能够极大提升 zsh 补全体验的插件。它通过 hook zsh 补全系统的底层函数 compadd 来截获补全列表,从而实现了在补全几乎任何玩意儿(命令行参数、变量、目录栈、文件)时都能使用 fzf 进行选择的功能。

快速预览:asciicast

项目地址: https://github.com/Aloxaf/fzf-tab

安装

偏好手动安装的用户

先随便 clone 到哪里

git clone https://github.com/Aloxaf/fzf-tab ~/somewhere

然后把 source ~/somewhere/fzf-tab.plugin.zsh 放到你的 ~/.zshrc 里。

各种插件管理器用户

以妙妙的 zinit 为例

zinit light Aloxaf/fzf-tab

Oh My Zsh 用户

先把本项目 clone 到你的插件目录,然后在插件列表里加上 fzf-tab

git clone https://github.com/Aloxaf/fzf-tab ~ZSH_CUSTOM/plugins/fzf-tab

注意事项: fzf-tab 对加载顺序有要求,推荐将它放在 compinit 之后、zsh-autosuggestionsfast-syntax-highlightingzsh-syntax-highlighting 之前加载。大概就像这个样子(仍然以 zinit 为例):

autoload -Uz compinit; compinit # zinit 用户这里可能是 zpcompinit; zpcdreplay
zinit light Aloxaf/fzf-tab      # fzf-tab 放在中间加载
zinit light zsh-users/zsh-autosuggestions    # 然后再是自动建议和语法高亮
zinit light zdharma/fast-syntax-highlighting

用法

用法非常简单,和平常一样按 Tab 就行了~

借助 fzf 提供的一些妙妙功能,你除了按 Enter 直接让结果上屏以外,甚至还可以

  1. Ctrl+Space 多选
  2. / 在本次结果上屏以后立即开始下一次补全(主要用于补全长路径)

配置

fzf-tab 的目标是兼容 zsh 补全系统的所有配置,不过这个目标我觉得除非我写一个 binary module,否则是不可能实现的……(考虑到 zsh 文档非常辣鸡,这个 binary module 我估计也写不出来

不过幸运的是,得益于 zsh 残念的文档,大部分人的对补全系统的配置应该也不会变态到 fzf-tab 承受不住。

如果将 zsh 的补全系统分为两部分:生成补全结果 和 展示补全结果。 那么在使用 fzf-tab 时,和“生成补全结果”相关的配置是可以生效的;而“展示补全结果”相关的配置,能不能生效就是一个未知数了(

fzf-tab 目前主动对与“展示”相关的两个常见配置做了兼容:

  • descriptions

用于设置不同补全“组”的描述文本

常见设置 zstyle ':completion:*:descriptions' format '[%d]'

因为 fzf 本身并不支持分组的功能,所以 fzf-tab 目前采用了用不同颜色来区分不同组。

  • list-colors

用于设置补全项的颜色,大部分人都是当成 LS_COLORS 用

常见设置 zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}

如果你只是当 LS_COLORS 用的话,fzf-tab 是可以完美支持的,甚至还能自动 resolve 符号链接并展示出来。 唯一的美中不足就是这是由纯 zsh 实现的,所以如果一次性补全上千个文件,速度会有点慢。

图片

fzf-tab 自身提供的配置参见 README

实验性功能

fzf 提供了 --preview 命令可以对当前选择的项目执行一段命令并将结果用小窗口展示出来。

利用这个命令我们还能做到一些 zsh 补全系统做不到的事情,比如在补全 cd 时预览目录的内容:

# 一些样板代码(未来可能会改变)
local extract="
# 提取当前选择的内容
in=\${\${\"\$(<{f})\"%\$'\0'*}#*\$'\0'}
# 获取当前补全状态的上下文
local -A ctxt=(\"\${(@ps:\2:)CTXT}\")
"

zstyle ':fzf-tab:complete:cd:*' extra-opts --preview=$extract'exa -1 --color=always ${~ctxt[hpre]}$in'

图片

又比如补全 kill 命令时预览命令行参数($extract 变量和上面是一样的)

zstyle ':fzf-tab:complete:kill:argument-rest' extra-opts --preview=$extract'ps --pid=$in[(w)1] -o cmd --no-headers -w -w' --preview-window=down:3:wrap

图片


支持一下

我现在用的 autosuggestions ,好像这个能替代那个?

我刚入门 zsh,也在用 zsh-autosuggestion,不知道这两个谁更强大。

两者并不冲突,zsh-autosuggestions 是实时提供一条建议,fzf-tab 是 zsh 补全系统的“前端”。我就是两者都在使用(

有点华而不实了

下载一个试试

不想折腾的可以直接 fish
3.0 版本解决了之前和 bash 不兼容问题

3.0 只是支持了 && || 吧,称之为改善比较合适。

这样啊,没有细看,看到支持 & 也不错了

_fzf_tab_complete:28: command not found: fzf

既然叫 fzf-tab,首先你得安装 fzf (

看到楼主截图中的 merge,我就在大脑中自动补全成 emerge --sync,然后我就想起了前几天玩的 Funtoo,哭了(っ °Д °;)っ

原来是要先装 fzf,在 wsl 下的 debian 没有出现提示,连 command not found 的提示都没有,换成 hyperv 虚拟机的 debian 后才知道要 apt install fzf
楼主,楼主,我有个问题。就比如我要补全 apt autopurge
输完 apt auto 后,按 TAB 键,没有 autopurge,然后我手动打完 autopurge 按回车,就变成了 auto,刚才打的 purge 没了。=====( ̄▽ ̄*)
还有个问题,我在打完 apt auto 后,按 TAB 键,然后我不想输这条命令,我想输 apt update,除了 Ctrl+C 外,还有其它方法吗?按退格键不行啊。
![Snipaste_2020-03-21_20-39-41.png]( https://i.loli.net/2020/03/21/2jLTkyvEVso3mti.png)


楼主,楼主,能不能增加一个新功能。
就比如我在输完 aria2c 后,按 TAB 补全,左边会出现它的参数,后边会出现该参数的用法。
就像是下面那张截图一样!ˋ( ° ▽、° )
![Snipaste_2020-03-22_19-00-03.png]( https://i.loli.net/2020/03/22/vVweBnyoxYdGACz.png)


> 输完 apt auto 后,按 TAB 键,没有 autopurge,然后我手动打完 autopurge 按回车,就变成了 auto,刚才打的 purge 没了
Emm,当前不支持直接把输入结果上屏,不过看了一下可以实现,明天加上这个功能。

> 除了 Ctrl+C 外,还有其它方法吗?
Ctrl+G (逃
如果将输入结果上屏的功能实现了以后你就可以直接删掉输入 update 了(

> 就比如我在输完 aria2c 后,按 TAB 补全,左边会出现它的参数,后边会出现该参数的用法。
大多数参数补全都是这样的吧?左边参数右边描述 https://i.loli.net/2020/03/23/Ql7JtYmZTi2c836.png (看了下 ariac 根本没有补全,随便生成了一个
你大概只是想要一份 ariac 的补全文件(奇怪,这么著名的工具竟然至今没有补全函数……

感谢大大, 这个对于一些 completion 选项超多的命令特别实用. 比如 git checkout :thumb: :thumb: :thumb:

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服