我在 MacOS El Capitan 上使用 zsh。我想知道如何参数化自动完成来解析别名。当我使用 bash 时,我.bash_profile
包含以下内容:
alias mdb "mongo -uadmin -pXXX --authenticationDatabase admin --host "
complete -W "$HOSTNAMES" mdb
HOSTNAMES
是超过 4000 个 FQDN 的列表。这样做我可以输入mdb someHost
tabtab以查看包含以 . 开头的所有主机的列表someHost
。一旦选择了正确的主机,命令就完成了mongo -uadmin -pXXX --authenticationDatabase admin --host someHostFoo
。
现在,我想使用 oh-my-zsh,所以我将上述行复制到我的.zshrc
文件中。但是,当主机名列表超过大约 1500 个条目时,自动完成功能将变为非常慢的。因此,我在文件中替换complete -W "$HOSTNAMES" mdb
为。但是,即使我将.今天我compctl -c "$HOSTNAMES" mdb
.zshrc
setopt complete_aliases
.zshrc
读人们应该更好地为命令编写完成函数,因为compctl
它已被弃用。我想出了这个,但这只会在包含很少主机名mdb hosts
tabtab时输入后建议主机名:$HOSTNAMES
#compdef mongo mdb
#autoload
_mongo_hosts(){
mhosts=$HOSTNAMES
}
local -a _1st_arguments
_1st_arguments=(
"--host:host to be connected to"
)
local expl
local -a mhosts
if (( CURRENT == 2 )); then
_describe -t commands "mongo subcommand" _1st_arguments
return
fi
case "$words[2]" in
hosts)
_mongo_hosts
_wanted mhosts expl 'known hosts' compadd -a mhosts ;;
esac
此外,通过这种方法,mdb
尚未被 取代mongo -uadmin -pXXX --authenticationDatabase admin --host
。
跟进
我放弃了上面显示的compdef
方法。我当前的解决方法是将以下两行添加到我的.zshrc
:
zstyle ':completion:*' completer _expand_alias _complete _ignored
zstyle ':completion:*:(ssh|scp|sftp|host):*' hosts $HOSTNAMES
第一行也是扩展别名,这里是我的别名mdb
。
第二行允许在使用ssh
、scp
、sftp
或等命令时循环显示所有主机名。host
通过这一行也可以实现同样的效果:
_hosts() {compadd $(echo $HOSTNAMES | tr "\n" " ")}
因此,使用这种方法,我必须先输入ssh someHost
tabtab,选择主机,然后替换ssh
为mdb
,以便完成mongo -uadmin -pXXX --authenticationDatabase admin --host someHostFoo
这可行,但并不完美。我希望拥有与使用 bash 相同的自动完成体验,由我的问题中第一行显示的两行实现。如何使用 zsh 和超过 4000 个主机名来实现这一点?谢谢你!
答案1
我找到了一个完全按照我想要的方式工作的解决方案。中只需要以下三行.zshrc
:
mdb() {mongo -uadmin -pXXX --authenticationDatabase admin --host "$@"}
compctl -k "($(echo $HOSTNAMES))" mdb
zstyle ':completion:*:(ssh|scp|sftp|host):*' hosts $(echo $HOSTNAMES)
该函数mdb()
取代了我以前的别名mdb
。该compctl
命令完成的功能mdb
类似于$HOSTNAMES
.该指令使用 的数组zstyle
完成诸如ssh
、scp
、sftp
和之类的命令。host
$HOSTNAMES