すでにZSH完了をサポートしている他のコマンドのラッパーであるコマンドのZSH完了ファイルを作成しています。他のコマンド補完で定義された「プライベート」ヘルパー関数を使用したいのですが、この単純なアプローチは機能しません。これまでこれが私が試しているものです:
#compdef wrapper
_arguments ':action:(foo bar baz)' ':target:_other_command_helper_func'
コマンドラインでこれを実行しようとすると、次の結果が表示されます。
_arguments:450: command not found: _other_command_helper_func
ここで私が望むようにできますか?
ベストアンサー1
プライベート機能がないため、すでに_other_command_helper_func
ロードされている場合に機能します。完了機能は通常自動的にロードされるため、このアプローチを使用すると、元のコマンドのwrapper
完了がすでに試行されている場合にのみ完了が機能することを意味します。
1つの解決策は、元のコマンドの完成関数ファイルを強制的にロードすることですが、これは簡単なことではありません。autoload -X +U
元のコマンドをロードする完成器を使用できますが、実際に行うことは、ヘルパー関数の定義やその他の初期化など、定義がファイル_other_command
の内容である関数(元のコマンドの名前であると仮定)を生成することです。_other_command
メイン関数呼び出しを介して。
_other_command () {
_other_command_helper_func () {
…
}
_other_command () {
…
}
_other_command "$@"
}
それを分析してみることができます。定義を制御できる場合は、初期化コードについていくつかの仮定を行うことができます。第三者であれば、リスクはさらに大きくなります。ほとんどの複雑な完成関数定義ファイルは初期化モデルとフォームの最後の行に従うので、通常は次_main_function "$@"
のように動作します。
if ((!$+functions[_other_command_helper_func])); then
autoload +X +U _other_command
functions[_other_command]=${functions[_other_command]%$'\n'*}
_other_command
fi
奇妙なエラーが発生すると、パーサーに影響を与えるオプションが原因で発生する可能性があります(_git
この方法でロードするとこの問題が発生しました)。これは私にとって効果的です。
load_helper_functions () {
emulate -LR zsh
if ((!$+functions[$1])) || [[ $functions[$1] = 'builtin autoload'* ]]; then
autoload +X +U $1
functions[$1]=${functions[$1]%$'\n'*}
$1
fi
}
load_helper_functions _git
または、コードで完了機能を実行し.zshrc
、完了コンテキストで実行されないため、自動的にブロックするようにすることもできます。_cvs 2>/dev/null
たとえば、CVSを使用するとこの問題が発生しました.zshrc
。
元の定義を制御できる場合は、より良いソリューションがあります。元のコマンドとラッパーの両方に同じ完了関数を使用できます($service
どのコマンドの引数が完了しているかを確認してください)。あるいは、別々のファイルでヘルパー関数を定義することもできます。