如何将Shell补全延迟到bash和zsh中的另一个命令?

时间:2019-04-01 01:25:20

标签: bash zsh bash-completion completion zsh-completion

我正在尝试编写一个将其他Shell实用程序包装到单个CLI中的Shell脚本实用程序,并试图使Shell完成功能在zsh和bash中工作。

例如,假设CLI名为util

util aws [...args] #=> runs aws
util docker [...args] #=> runs docker
util terraform [...args] #=> runs terraform

理想情况下,我想要的是zsh和bash完成中能够独立于包装脚本的完成实现而说“像其他命令Y一样完成此子命令X”的方法。

类似的东西:

compdef 'util aws'='aws'
compdef 'util docker'='docker'
compdef 'util terraform'='terraform'

一个扩展目标是允许在另一个二进制文件中完成对一个子命令的任意子命令:

util aws [...args] #=> completes against `aws`
util ecr [...args] #=> completes against `aws ecr`

这有可能吗?我一直在尝试模拟单个二进制文件的完成脚本,但是在编写其他完成脚本的方式上有很大的不同。

1 个答案:

答案 0 :(得分:1)

我对zsh一无所知,但是我可以为bash提供解决方案。它使用_complete函数进行委托(我在muru's suggestion之后发现-很好的调用!)。

该函数的第二部分提供util命令本身的完成,我认为这里只是子命令的列表。当然,您可以根据自己的需要进行调整。

第一部分在键入完整的子命令的情况下处理委派,并根据子命令的完成情况选择完成的目标。

功能

_delegate() {
  local cur subs
  cur="${COMP_WORDS[COMP_CWORD]}" # partial word, if any
  subs="ssh aws docker terraform"
  if [[ $COMP_CWORD == 2 ]]; then
    # Two whole words before the cursor - delegate to the second arg
    _command $2
  else
    # complete with the list of subcommands 
    COMPREPLY=( $(compgen -W "${subs}" -- ${cur}) )
  fi
}

安装

njv@pandion:~$ complete -F _delegate util

演示

1d [njv@eidolon:~] $ util
aws        docker     ssh        terraform
1d [njv@eidolon:~] $ util ssh
::1                        gh                         ip6-localhost              ubuntu.members.linode.com
eidolon                    github.com                 ip6-loopback
ff02::1                    ip6-allnodes               localhost
ff02::2                    ip6-allrouters             ubuntu
1d [njv@eidolon:~] $ util ssh ip6-
ip6-allnodes    ip6-allrouters  ip6-localhost   ip6-loopback