fzf-tab - 使用 fzf 作为 zsh 的补全选择菜单

2020-03-17 15:34:06 +08:00
 aloxaf

简介

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

快速预览:

项目地址: 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 目前主动对与“展示”相关的两个常见配置做了兼容:

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

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

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

用于设置补全项的颜色,大部分人都是当成 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

8900 次点击
所在节点    Linux
17 条回复
lcdtyph
2020-03-17 15:48:42 +08:00
支持一下
Tink
2020-03-17 15:50:27 +08:00
我现在用的 autosuggestions ,好像这个能替代那个?
jmyz0455
2020-03-17 16:03:01 +08:00
@Tink 我刚入门 zsh,也在用 zsh-autosuggestion,不知道这两个谁更强大。
aloxaf
2020-03-17 16:17:55 +08:00
@Tink 两者并不冲突,zsh-autosuggestions 是实时提供一条建议,fzf-tab 是 zsh 补全系统的“前端”。我就是两者都在使用(
wweir
2020-03-17 16:28:28 +08:00
有点华而不实了
s154942630
2020-03-18 08:19:23 +08:00
下载一个试试
Varobjs
2020-03-18 09:42:24 +08:00
不想折腾的可以直接 fish
3.0 版本解决了之前和 bash 不兼容问题
aloxaf
2020-03-18 10:04:55 +08:00
@Varobjs 3.0 只是支持了 && || 吧,称之为改善比较合适。
Varobjs
2020-03-18 10:54:43 +08:00
@aloxaf 这样啊,没有细看,看到支持 & 也不错了
leion8310
2020-03-18 14:54:20 +08:00
_fzf_tab_complete:28: command not found: fzf
aloxaf
2020-03-18 16:34:58 +08:00
@leion8310 既然叫 fzf-tab,首先你得安装 fzf (
404error
2020-03-21 20:08:46 +08:00
看到楼主截图中的 merge,我就在大脑中自动补全成 emerge --sync,然后我就想起了前几天玩的 Funtoo,哭了(っ °Д °;)っ
404error
2020-03-21 20:53:08 +08:00
原来是要先装 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)
404error
2020-03-22 19:06:29 +08:00
@aloxaf
楼主,楼主,能不能增加一个新功能。
就比如我在输完 aria2c 后,按 TAB 补全,左边会出现它的参数,后边会出现该参数的用法。
就像是下面那张截图一样!ˋ( ° ▽、° )
![Snipaste_2020-03-22_19-00-03.png]( https://i.loli.net/2020/03/22/vVweBnyoxYdGACz.png)
aloxaf
2020-03-23 00:58:35 +08:00
@404error
> 输完 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 的补全文件(奇怪,这么著名的工具竟然至今没有补全函数……
ouchxp
2020-10-16 04:16:36 +08:00
感谢大大, 这个对于一些 completion 选项超多的命令特别实用. 比如 git checkout :thumb: :thumb: :thumb:
fo0o7hU2tr6v6TCe
2021-08-06 11:25:09 +08:00
@aloxaf 想问一下 楼主,搜索完成后再终端显示可选择的菜单栏 这整个流程是 怎么实现的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/653576

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX