私のzshrcには、ディレクトリを作成して入力するための次の機能が含まれています。
function mcd () {
mkdir -p "$*" && cd "$*"
}
関数自体はうまく機能しますが、完了後に奇妙な動作が発生します。たとえば、入力を開始しmcd ~/
てからを押すとTabメッセージが表示されます。
_mtools_drives:3: command not found: mtoolstest
挿入ポイントに挿入され、何もしません。私が望むのは、コマンドが次のように完了することですmkdir
。 zshは私に既存のディレクトリの名前を与える必要があります。
mcd
完了目的のためにzshを同じように処理する必要があることをどのように指示しますかmkdir
?
答え1
次のコードスニペットはmcd
次のように完了しますmkdir
。
compdefas () {
if (($+_comps[$1])); then
compdef $_comps[$1] ${^@[2,-1]}=$1
fi
}
compdefas mkdir mcd
仕組みは、現在の完了設定を見つけることですmkdir
。関数の完成コード(通常は完成関数の名前)は連想配列に格納されます_comps
。したがって、ステートメントはcompdef $_comps[mkdir] mcd
今完成したのとmcd
同じ方法で完成する必要があります。mkdir
上記の関数はいくつかの詳細を追加します。
- テストでは、完了方法が指定されていない
(($+_comps[$1]))
場合、$1
他のパラメータに対して完了方法が設定されていないことを確認します。 ${@[2,-1]}
は2番目の引数で始まる関数引数のリストなので、複数のコマンド名を指定して補完を定義できます。実際には${^@[a,-1]}
これです各配列要素の配列拡張の周囲のテキストをコピーします。。=$1
設定使用するサービス名。これは、補完機能が密接に関連する複数のコマンドを処理するいくつかのコマンドにのみ重要です。たとえば、補完関数は and だけでなく、while のデフォルトの動作を使用して完了のための動作を使用_gzip
できます。gzip
gunzip
pigz
unpigz
compdef _gzip foo
foo
_gzip
compdef _gzip foo=pigz
foo
_gzip
pigz
特定のケースに戻ると、デフォルトの補完はディレクトリをmkdir
提供するだけでなく、関数がサポートしないオプションも提供します。したがって、実際にmcd
既存のディレクトリを完成させるように定義する方がよいでしょう。 Zshにはヘルパー機能(非文書化ラッパー)が付属しています。_files
)。
compdef _directories mcd
このように奇妙に見える完成が現れるのは、mcd
それがかつてかなり広範なコマンドの集まりだったコマンドの名前だったからです。ツールボックス。
答え2
compdef
次のフォームを使用してください。
compdef [ -ane ] function name
したがって、1つのアイデアは、以下を介して関数をname
指すことです。mcd
_mkdir
compdef _mkdir mcd
ただし、これは多少不正確です。mkdir
完了には提供しないさまざまなフラグが提供されるためですcd
。より直接的な方法は、ディレクトリで行うことです。
compdef _directories mcd