V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
aloxaf
V2EX  ›  Linux

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

  •  1
     
  •   aloxaf ·
    Aloxaf · 2020-03-17 15:34:06 +08:00 · 8755 次点击
    这是一个创建于 1703 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简介

    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
    

    图片

    17 条回复    2021-08-06 11:25:09 +08:00
    lcdtyph
        1
    lcdtyph  
       2020-03-17 15:48:42 +08:00
    支持一下
    Tink
        2
    Tink  
       2020-03-17 15:50:27 +08:00
    我现在用的 autosuggestions ,好像这个能替代那个?
    jmyz0455
        3
    jmyz0455  
       2020-03-17 16:03:01 +08:00
    @Tink 我刚入门 zsh,也在用 zsh-autosuggestion,不知道这两个谁更强大。
    aloxaf
        4
    aloxaf  
    OP
       2020-03-17 16:17:55 +08:00
    @Tink 两者并不冲突,zsh-autosuggestions 是实时提供一条建议,fzf-tab 是 zsh 补全系统的“前端”。我就是两者都在使用(
    wweir
        5
    wweir  
       2020-03-17 16:28:28 +08:00
    有点华而不实了
    s154942630
        6
    s154942630  
       2020-03-18 08:19:23 +08:00
    下载一个试试
    Varobjs
        7
    Varobjs  
       2020-03-18 09:42:24 +08:00 via Android
    不想折腾的可以直接 fish
    3.0 版本解决了之前和 bash 不兼容问题
    aloxaf
        8
    aloxaf  
    OP
       2020-03-18 10:04:55 +08:00
    @Varobjs 3.0 只是支持了 && || 吧,称之为改善比较合适。
    Varobjs
        9
    Varobjs  
       2020-03-18 10:54:43 +08:00
    @aloxaf 这样啊,没有细看,看到支持 & 也不错了
    leion8310
        10
    leion8310  
       2020-03-18 14:54:20 +08:00
    _fzf_tab_complete:28: command not found: fzf
    aloxaf
        11
    aloxaf  
    OP
       2020-03-18 16:34:58 +08:00   ❤️ 1
    @leion8310 既然叫 fzf-tab,首先你得安装 fzf (
    404error
        12
    404error  
       2020-03-21 20:08:46 +08:00
    看到楼主截图中的 merge,我就在大脑中自动补全成 emerge --sync,然后我就想起了前几天玩的 Funtoo,哭了(っ °Д °;)っ
    404error
        13
    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
        14
    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
        15
    aloxaf  
    OP
       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
        16
    ouchxp  
       2020-10-16 04:16:36 +08:00
    感谢大大, 这个对于一些 completion 选项超多的命令特别实用. 比如 git checkout :thumb: :thumb: :thumb:
    fo0o7hU2tr6v6TCe
        17
    fo0o7hU2tr6v6TCe  
       2021-08-06 11:25:09 +08:00
    @aloxaf 想问一下 楼主,搜索完成后再终端显示可选择的菜单栏 这整个流程是 怎么实现的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5417 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:55 · PVG 13:55 · LAX 21:55 · JFK 00:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.