ここで愚かなことをしている場合はご容赦ください。ドキュメントは膨大で、検索してもまだ何も見つかりませんでした。
fab
というカスタムスクリプトのシェル補完を作成しようとしています 。 bashの場合は簡単で、/etc/bash_completion.d
にドロップするだけです。 そして彼らは働きます。しかし、おやおや、zshはPITAです…
完了関数_fab
があります compdef _fab fab
で有効にすると正常に動作します 。 /usr/share/zsh/vendor-completions/_fab
に入れました これはすでに私の$fpath
にありました 。ファイルは#compdef fab
で始まります compdef _fab fab
で終わります 。よさそうだ:
$ type _fab
_fab is an autoload shell function
しかし、新しいシェルを開始するたびに、fab
補完が機能しませんでした(vendor-completions
の他の関数 、_docker
のように 、 私たちは大丈夫です)。 compinit
その特定のシェルについてこれを修正しました。 rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit
永続的に機能するようにします(5.1.1 =私のzshバージョン)。
質問:
- 何をいつ読み取るか
~/.zcompdump
初期完了を設定するには? -
man zshall
言う:次のcompinitの呼び出しは、完全な初期化を実行する代わりに、ダンプされたファイルを読み取ります。
その場合は、
compinit
~/.zcompdump
を削除する前に完了を修正しませんでした 、 右?何か足りないのですか? -
~/.zcompdump-$(hostname)-5.1.1
とは.zcompdump
とどのように関連していますか ?唯一の違いは、~/.oh-my-zsh/completions
にある1つの補完です。 ($ZSH
のため~/.oh-my-zsh
を指します )。それはoh-my-zshのことですか? - これらの補完を再配布可能なパッケージにパッケージ化するか、インストーラースクリプトを作成する場合、zsh補完をどこに配置し、すべてが正常に機能するようにインストール中に他に何をすべきですか?
Ubuntu 16.04、18.04、19.04をターゲットにしていますが、ディストリビューション固有ではない情報を歓迎します。これをUbuntu16.04でzsh5.1.1と最近のoh-my-zshでテストしています。
承認された回答:
TL、DR:通常の操作では、ファイルを適切なディレクトリにドロップするだけです。テスト中に、キャッシュファイル(.zcompdump
)を削除する必要があります デフォルトでは、ユーザーは別の場所に配置でき、oh-my-zshは別の場所に配置します。
簡単な答えは、最初の行が#compdef fab
であるファイルに完了関数を書き込むことです。 。ファイルは$fpath
のディレクトリにある必要があります 。
このファイルには、関数本体、または関数の定義とそれに続く関数の呼び出しのいずれかを含めることができます。つまり、ファイルに次のようなものが含まれています
#compdef fab
_arguments …
または
#compdef fab
function _fab {
_arguments …
}
_fab "[email protected]"
ファイルは$fpath
に存在する必要があります compinit
の前 実行されます。つまり、.zshrc
内の順序に注意を払う必要があります :最初にカスタムディレクトリを$fpath
に追加します 、次にcompinit
を呼び出します 。 oh-my-zshなどのフレームワークを使用する場合は、必ずカスタムディレクトリを$fpath
に追加してください。 oh-my-zshコードの前。
compinit
完了システムを初期化する関数です。 $fpath
内のすべてのファイルを読み取ります 最初の行で魔法のディレクティブ#autoload
をチェックします および#compdef
。
.zcompdump
compinit
によって使用されるキャッシュファイルです 。 ~/.zcompdump
デフォルトの場所です。 compinit
を実行するときに、別の場所を選択できます 。 Oh-my-zshはcompinit
を呼び出します -d
を使用 変数ZSH_COMPDUMP
で指定された別のキャッシュファイル名を使用するオプション 、デフォルトは
ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
ホスト名は、ホームディレクトリがマシン間で共有されていて、異なるマシンに異なるソフトウェアがインストールされている可能性がある人のために含まれています。キャッシュファイルはバージョン間で互換性がないため、zshバージョンが含まれています(バージョンごとに変わるコードが含まれています)。
関連:CTRL + Vはvimで何をしますか?
あなたの問題はすべて古いキャッシュファイルが原因だと思います(そしてそれはあなたに状況を過度に複雑にしました)。残念ながら、キャッシュファイルが古くなっているかどうかを判断するzshのアルゴリズムは、おそらく速度の観点から完全ではありません。 $fpath
上のファイルのコンテンツやタイムスタンプはチェックされません 、それはそれらを数えるだけです。 .zcompdump
ファイルは
#files: 858 version: 5.1.1
zshのバージョンとファイルの数が正しい場合、zshはキャッシュファイルをロードします。
キャッシュファイルには、コマンド名間の関連付けのみが含まれ、完了関数のコードは含まれません。キャッシュが透過的に機能する一般的なシナリオは次のとおりです。
-
$fpath
に新しいファイルを追加する場合 、これによりキャッシュが無効になります。 - より一般的には、
$fpath
でファイルを追加および削除する場合 、および削除されたファイルの総数が削除されたファイルの総数と同じではない場合、これによりキャッシュが無効になります。 - ファイルを
$fpath
の別のディレクトリに移動した場合 名前を変更しなくても、キャッシュにあるものには影響しないため、キャッシュは正しいままです。 -
$fpath
内のファイルを変更する場合 最初の行を変更しなくても、これはキャッシュ内の何にも影響を与えないため、キャッシュは正しいままです。
キャッシュが無効になるが、zshがそれを認識しない一般的なシナリオを次に示します。
-
$fpath
にいくつかのファイルを追加します まったく同じ数のファイルを削除します。 -
$fpath
でファイルの名前を変更します 。 -
#compdef
を追加または変更します (または#autoload
)ファイルの先頭の行。
その最後のポイントは、テスト中に噛む傾向があるものです。 #compdef
を変更した場合 行では、.zcompdump
を削除する必要があります ファイルを作成してzshを再起動します(またはcompinit
を再実行します 。
補完を再配布可能なパッケージに入れる場合は、補完ファイルをシステム全体の$fpath
にあるディレクトリにドロップするだけです。 。 Ubuntuパッケージの場合、適切な場所は/usr/share/zsh/vendor-completions
です。 。 /usr/local
の下にインストールされているものの場合 、それは/usr/local/share/zsh/site-functions
。必要なのはそれだけです。
透過的でないことの1つは、#compdef
を変更する必要があるかどうかです。 アップグレードの行、または一部のファイルを削除または名前変更した場合。このような場合、ユーザーはキャッシュファイルを削除する必要がありますが、これはマルチユーザーマシンにインストールされるパッケージから実行できることではありません。