ここで愚かなことをしている場合はご容赦ください。ドキュメントは膨大で、検索してもまだ何も見つかりませんでした。
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を変更する必要があるかどうかです。 アップグレードの行、または一部のファイルを削除または名前変更した場合。このような場合、ユーザーはキャッシュファイルを削除する必要がありますが、これはマルチユーザーマシンにインストールされるパッケージから実行できることではありません。