自定義命令的動態 zsh 自動完成
我正在嘗試為我編寫的一些自定義函式編寫完成函式,但即使是最基本的函式似乎也很難。
一個範例函式是:
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 repo,但似乎找不到與我需要的類似的東西。
任何幫助入門將不勝感激!
更新
根據@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
乍一看,zsh Completion System似乎很複雜,很難掌握。讓我們嘗試一個例子。
您需要知道的第一件事是
zsh
完成系統將從$fpath
. 確保您的完成目錄出現在:print -rl -- $fpath
(如果您使用的是oh-my-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
函式和state
變數的 zsh 補全系統文件。此外,您將需要更改(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
,則已載入)