如何自定义Shell(Fish)的自动补全规则?

默认fish能自动补全的命令已经相当多了,常见的apt-get,rpm等都没问题,但今天却发现没有lsusb的补全规则,查看了下文档,发现规则比bash-completion简单不少,记录下~

简单补全

1. 建立自动补全规则文件
默认自动补全路径由全局变量$fish_complete_path定义,
我选取了位置/usr/share/fish/completions,在其中建立lsusb.fish文件
2. 书写补全规则
先查看下lsusb有哪些选项

fish自带complete命令用于定义补全规则
使用方法是:
complete -c 命令 -s 短选项 -l 长选项 --description "描述"
譬如我想有lsusb的-v(–verbose)选项的自动补全,就可以这样写:
complete -c lsusb -s v -l verbose --description "Increase verbosity (show descriptors)"
这里:
-c lsusb 是我希望添加补全的命令 -s 后接短选项,类似-v形式
-l 后接长选项,类似–verbose形式
–description 是选项的解释,可有可无
仿照例子将如下命令添加到lsusb.fish文件中

<code>complete -c lsusb -s v -l verbose --description "Increase verbosity (show descriptors)"  
complete -c lsusb -s s  --description "Show only devices with specified device and/or bus numbers (in decimal)"  
complete -c lsusb -s d --description "Show only devices with the specified vendor and product ID numbers (in hexadecimal)"  
complete -c lsusb -s D -l device --description "Selects which device lsusb will examine"  
complete -c lsusb -s t -l tree --description "Dump the physical USB device hierarchy as a tree"  
complete -c lsusb -s V -l version --description "Show version of program"  
complete -c lsusb -s h -l help --description "Show usage and help"  
</code>

如此输入lsusb -敲tab键就会显示如下效果

高级补全
一些命令不光有基于-或–如此形式的选项补全,还有自身特点特定的补全,如mount的挂载点补全,su的用户补全,ssh的主机补全,这是怎么做到的呢? 还以lsusb为例,lsusb -s 001:001是列出第一个bus的第一个device信息,我希望当输入lsusb -s时,按下tab会列出当前主机所有bus和device让我选择
complete提供了-x和-a来实现这样的高级补全
complete -x -c lsusb -s s -a '(__fish_complete_usb)' --description "Show only devices with specified device and/or bus numbers (in decimal)"
-x 告诉complete不要用tab默认的文件补全,而是要用-a告诉的参数来补全
-a “参数列表” 是一个列表,里面是complete参数补全的依据,这里我用__fish_complete_usb 来实时生成,而没有写死
函数__fish_complete_usb是由/usr/share/fish/functions/__fish_complete_usb.fish定义的,用来生成设备列表

<code>function __fish_complete_usb  
        lsusb | awk '{print $2 ":" $4}'| cut -c1-7
end  
</code>

如此lsusb -s就能基于总线设备号来补全了 

 

补充:*lsusb completion*已经被fish官方采纳,这是我贡献的第一个开源项目,好高兴!