我正在尝试为我编写的一些自定义函数编写完成函数,但即使是最基本的函数似乎也确实很困难。
一个示例函数是:
function eb_instances() {
if [ "$#" -ne 2 ]; then
echo "Usage eb_instances <aws profile name> <environment name>"
echo "e.g.:"
echo " eb_instances production kraken-prod-api"
return 1
fi
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" "Name=tag:Name,Values=$2" --profile=$1 --output=json | jq -r ".Reservations[].Instances[].PrivateIpAddress"
}
这有两个位置参数,<aws profile name>
并且<environment name>
<aws profile name>
我希望通过运行 来动态地使用 的 完成选项,并且通过运行我调用的另一个函数来动态地使用 的sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '
完成选项。<environment name>
eb_names
我发现文档非常稀疏且难以理解。我还看到了类似命令的 zsh-completions 存储库,但似乎找不到与我需要的类似的东西。
任何入门帮助将不胜感激!
更新
基于@cuonglm 的回答, 我用了:
#compdef ebinstances
_ebinstances() {
local state
_arguments \
'1: :->aws_profile'\
'*: :->eb_name'
case $state in
(aws_profile) _arguments '1:profiles:($(sed -n -E "s/\[([a-zA-Z0-9_\-]+)\]/\1/p" ~/.aws/credentials | tr \\n " "))' ;;
(*) compadd "$@" foo bar
esac
}
_ebinstances "$@"
我在原来的问题中忘记提到的是,我还希望第二个参数的完成依赖于第一个参数(两者都是基于动态执行一些代码),例如:
$ eb_instances <cursor>TAB
cuonglm test
得到我想要的完成。一旦我选择第一个,并尝试自动完成:
$ eb_instances cuonglm <cursor>TAB
我想通过执行来生成完成选项eb_names cuonglm
,如果可能的话,还可以深入了解完成,例如,如果正确的候选者是foo-bar
,
$ eb_instances cuonglm foo<cursor>TAB
我想通过执行生成完成选项eb_names cuonglm foo
答案1
起初,zsh补全系统似乎非常复杂,难以掌握。让我们尝试一个例子。
您需要知道的第一件事是zsh
补全系统将从 加载补全函数$fpath
。确保您的完成目录出现在:
print -rl -- $fpath
(如果您正在使用哦我的zsh,.oh-my-zsh/completions
是在$fpath
.您只需创建它并将完成功能放在那里即可。)
现在,您必须为您的函数创建一个完成文件。它的名称必须以下划线 ( _
) 加上您的函数名称开头。在你的例子中,它的名字是_eb_instances
.
将这些行添加到_eb_instances
文件中:
#compdef eb_instances
_eb_instances() {
local state
_arguments \
'1: :->aws_profile'\
'*: :->eb_name'
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "$@" prod staging dev
esac
}
_eb_instances "$@"
你完成了。保存文件并启动新会话以测试完成情况。你会看到这样的东西:
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
_arguments
您可以阅读有关函数和变量的 zsh 补全系统文档state
。此外,您还需要更改(cuonglm test)
您的sed
命令并更改prod staging dev
您的eb_names
功能。
如果您想根据传递的第一个参数生成第二个参数,您可以使用该$words[2]
变量:
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "$@" $(echo $words[2]) ;;
esac
替换echo
为您的实际功能。就你而言,它是$(eb_names $words[2])
.
如果您仍然遇到问题,只需在then 调用完成中将_eb_instances
和定义为:eb_instances
.zshrc
compdef _eb_instances eb_instances
您需要使用以下命令初始化完成系统:
autoload -U compinit
compinit
(如果您使用过oh-my-zsh
,则已加载)