scoop など、サブコマンドを持っていて、zsh の補完が公式から定義されていないコマンドの補完をささっと作るテンプレートを作った。
ファイル名は補完対象のコマンド名の先頭にアンダースコア_
を付与した名前にする。
このファイルを _fpath
の通っているディレクトリに置けばOK。
_scoop
#cmddef scoop
# ↑補完対象のコマンド名を記述する
function (){
# 自動で生成される変数。ローカル化しておく
local context state line
typeset -A opt_args
# サブコマンド1つにつき「サブコマンド名:説明文」の行を作る。「:説明文」は省略可能
# 補完文字列に「:」を使う場合はバックスラッシュでエスケープする
local subcmd_text=$(cat <<'_EOS'
alias:Manage scoop aliases
bucket:Manage Scoop buckets
cache:Show or clear the download cache
cat:Show content of specified manifest. If available, `bat` will be used to pretty-print the JSON.
checkup:Check for potential problems
cleanup:Cleanup apps by removing old versions
config:Get or set configuration values
create:Create a custom app manifest
depends:List dependencies for an app
download:Download apps in the cache folder and verify hashes
export:Exports (an importable) list of installed apps
help:Show help for a command
hold:Hold an app to disable updates
home:Opens the app homepage
info:Display information about an app
install:Install apps
list:List installed apps
prefix:Returns the path to the specified app
reset:Reset an app to resolve conflicts
search:Search available apps
shim:Manipulate Scoop shims
status:Show status and check for new app versions
unhold:Unhold an app to enable updates
uninstall:Uninstall an app
update:Update apps, or Scoop itself
virustotal:Look for app's hash on virustotal.com
which:Locate a shim/executable (similar to 'which' on Linux)
_EOS
)
# 上記で作った「サブコマンド名:説明文」を行区切りで配列に変換する
local subcmds=("${(@f)subcmd_text}")
# _arguments コマンド:文脈に応じて補完の振り分けをしたり登録したりするコマンド
# 補完対象文字列が "-" で始まっていなければ(=非オプションならば)、$state 変数に "subcmd" が代入される
_arguments : '*::scoop-subcmd:->subcmd' # scoop-subcmd の部分は補完時に表示されるメッセージであり任意の文字に置き換える
if [[ "$state" == "subcmd" ]]; then
if (( CURRENT == 1 )); then # 現在の補完が1つ目の単語のとき(CURRENT も自動生成される変数)
# _descripbe コマンド:配列変数名を指定すればその配列を補完として登録するコマンド
# 先ほど生成した subcmds 配列変数を補完候補として指定する
_describe "scoop-subcmd" subcmds # _describe <description> <array-name>
else
# それ以降の補完にはファイル名を補完させる
_arguments : '*::Files:_files'
# もしそれ以降の補完を作る場合は自動で生成される配列変数 words を $words[1] を見てサブコマンドを判定して分岐させるとよい
fi
fi
}