私がここで愚かなことをしたならば、許してください。ドキュメントは膨大で検索してもまだ何も出ていません。
というカスタムスクリプトのシェル補完機能を作成しようとしています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
?唯一の違いは、完了の1つ~/.oh-my-zsh/completions
($ZSH
を指すので~/.oh-my-zsh
)が完了の1つであることです。これはoh-my-zshの仕事ですか? - これらの補完エントリを再頒布可能パッケージにパッケージ化したり、インストーラスクリプトを生成したい場合は、zsh補完エントリをどこに配置する必要がありますか?すべてが正しく機能していることを確認するには、インストール中に何をすべきですか?
Ubuntu 16.04、18.04、19.04を対象としていますが、distro関連情報ではない場合は大歓迎です。私はzsh 5.1.1と最近oh-my-zshを使ってUbuntu 16.04でテストしています。
答え1
TL、DR:通常の作業では、ファイルをそのディレクトリに配置するだけです。テスト時にキャッシュファイルを削除する必要があります(.zcompdump
デフォルトでは、ユーザーは別の場所に保存できますが、oh-my-zshは別の場所に保存します)。
簡単な答えは、最初の行を持つファイルに完成関数を書くことです。#compdef fab
。ファイルはのディレクトリになければなりません$fpath
。
ファイルには関数本体を含めることもできますし、関数定義と関数呼び出しを含めることもできます。つまり、ファイルには次の内容が含まれています。
#compdef fab
_arguments …
または
#compdef fab
function _fab {
_arguments …
}
_fab "$@"
$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バージョンが含まれています(バージョンごとに異なるコードが含まれています)。
あなたのすべての問題は古いキャッシュファイルによって引き起こされると思います(これは状況が複雑すぎます)。残念ながら、キャッシュされたファイルが古いかどうかを確認するZshアルゴリズム完璧ではありません。おそらくスピードのためです。ファイルの内容やタイムスタンプを確認せずに数だけ$fpath
カウントします。ファイルは.zcompdump
次の行で始まります。
#files: 858 version: 5.1.1
zshバージョンとファイル数が正しい場合、zshはキャッシュされたファイルをロードします。
キャッシュファイルには、完了機能へのコードではなくコマンド名間の接続のみが含まれます。キャッシュの透明性が機能するいくつかの一般的なシナリオは次のとおりです。
- 新しいファイルが追加されると、
$fpath
キャッシュは無効になります。 - より一般的には、ファイルを追加および削除し、
$fpath
削除されたファイルの総数が削除されたファイルの総数と異なる場合、キャッシュは無効になります。 - 名前を変更せずにファイルを別のディレクトリに移動すると、キャッシュ内の
$fpath
どのエントリにも影響しないため、キャッシュは正しく保持されます。 - 最初の行を変更せずにファイルを変更すると、キャッシュ内の
$fpath
どのエントリにも影響を与えないため、キャッシュは正しいままです。
キャッシュが無効になっているがzshがそれを認識しないいくつかの一般的なシナリオは次のとおりです。
- いくつかのファイルを追加し
$fpath
、まったく同じ数のファイルを削除します。 - ファイル名を
$fpath
。 #compdef
ファイルの上部に(または)行を追加または変更できます。#autoload
この最後のポイントは、テスト中に最も難しい問題です。この行を変更した場合は、ファイルを削除してzshを再起動(または再実行)#compdef
する必要があります。.zcompdump
compinit
再頒布可能パッケージに完成ファイルを挿入する場合は、完成ファイルをシステム全体のディレクトリに配置するだけです$fpath
。 Ubuntuパッケージ/usr/share/zsh/vendor-completions
の場合、適切な場所はです/usr/local
。/usr/local/share/zsh/site-functions
それはあなたがしなければならないすべてです。
透明でないことの1つは、#compdef
アップグレードで行を変更する必要があるか、特定のファイルを削除するか名前を変更する必要があるかです。この場合、ユーザーはキャッシュファイルを削除する必要があります。これは、マルチユーザーコンピュータにインストールされているパッケージでは実行できない操作です。