Bashタブ補完スクリプトをzshで使用できますか?


87

ApacheのHadoop用のBashタブ補完スクリプトがあります。通常、私は日常のシェルとしてzshを使用します。必要なときにかなりbashのようになる傾向がありますが、タブ補完システムはそれらの間で根本的に異なっているように見えます。既存のbash-tab-completion定義をzshで機能するように「変換」する簡単な方法はありますか?これに多くの時間を費やしたくはありませんが、簡単であれば、適度な労力を節約できます。

回答:


39

このページから(2010/ 01/05日付):

Zshはbash補完関数を処理できます。zshの最新の開発バージョンには関数bashcompinitがあり、実行するとzshがbashの完了仕様と関数を読み取ることができます。これは、zshcompsysのマニュアルページに記載されています。これを使用するには、compinitの後いつでもbashcompinitを実行するだけです。これは、bashビルトインに対応する完全なcompgen関数を定義します。


良いニュース:これはうまくいくはずだと思うので、どうもありがとう。悪いニュース:何らかの理由で、これを達成しようとしているシステムは、SSH経由でログインしたときに/ etc / zshrcをロードしていないようです。ログインプロセスについて、なぜそうなるのかを理解するのに十分な知識がありません。たぶん時間が...別の質問をする
Coderer

1
@Coderer:まず、「/ etc / zshrc」と言います。私のシステムでは、それは/etc/zsh/zshrcです。:また、(それらはzshの起動時に調達された順にリストされている)逆の順序で、次のファイルをチェックし/etc/zsh/zshenv$ZDOTDIR/.zshenv/etc/zsh/zprofileおよび$ZDOTDIR/.zprofile(おそらく~/.zprofileかどうかを確認するために)RCS変数が設定されていません。もしそうなら、それはそれが設定されていないファイルの後の後続のファイルが供給されるのを妨げるでしょう。最後に、ユーザーのシェルをチェックして、シェルが含まれて/etc/passwdいることzshを確認し、-f引数がないことを確認します。
追って通知があるまで一時停止します。

すべてのフィードバックに感謝します-私は#1の古典的なプログラマーハックである「stdoutdebugging」(各スタートアップスクリプトのエコーステートメント)に頼り、問題を見つけました。何らかの理由で、/ etc / zprofileはさまざまな/etc/profile.dスクリプトを調達しており、それらは/ etc / zshrcで再び調達れていました。autoloadステートメントを/ etc / zprofileの先頭に移動するだけで、問題が修正されました。
コーダー2010

157
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file

10
これは、bashcompinitの使用方法説明しているため、より適切な回答です。良くやった。
パイロスペード2014

5
おかげで、すばらしい答えです。残念ながら、スクリプトが_init_completion bashコマンドを使用している場合、これは機能しません。
0fnt 2014

6
これは私にはうまくいきませんでした。まだcomplete:13: command not found: compdefエラーが発生していました。
Jatin Kumar 2015

それが機能しない場合は、スクリプトを確認してください(doh:))-if is-bash上部にチェックがある可能性があります。
olejorgenb 2015

これ_get_comp_words_by_refは、で定義されていないスクリプトでは機能しませんbashcompinit。ただし、ほとんどの補完ではこの関数を使用しません。
フランクリンユー

39
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script

私はzsh 5.0.2 (x86_64-apple-darwin13.0) 〜/ .zshrcなしでzsh実行しており、上記のシーケンスは新しく生成されたzshシェルで機能しました。

ヒントをくれたgit-completion.bashスクリプトに感謝します:D


上記の3行の詳細については、以下をお読みください。

バッシュは、構築された自動補完のサポートに素晴らしい持っていますが、bashの自動補完スクリプトはzshの環境として、直接のzsh動作しないように不可欠な、bashのオートコンプリートヘルパー関数を持っていませんcompgencomplete。これは、zshセッションを高速に保つために行われます。

これらの日のような適切な補完スクリプトが同梱されてzshのcompinitbashcompinit、bashの自動補完スクリプトをサポートするために必要な機能を有しています。

autoload <func_name>:自動ロードはbashではなくzshで定義されていることに注意してください。コマンドautoloadによって返されたディレクトリパスで名前が付けられたファイルを探し、fpath最初に呼び出されたときに同じファイルをロードするように関数にマークを付けます。

  • -U: compinitやbashcompinitなどの関数をロードするときにエイリアスを無視します
  • + X:名前付き関数を今すぐロードし、実行しないでください

私のシステム上の例えばecho $fpathリターン/usr/share/zsh/site-functions/usr/share/zsh/5.0.5/functionsの両方compinitbashcompinitでご利用いただけます/usr/share/zsh/5.0.5/functions

また、ほとんどの人にとってautoload -U +X bashcompinit && bashcompinitは、git autocompleteのような他のスクリプトや独自のスクリプト~/.zshrcが実行している可能性があるため、必要なだけかもしれませんがautoload -U +X compinit && compinit、両方を実行するだけで安全です。


どのようなもの-U+Xするために?
jmk 2015年

詳細で回答を更新しました。
Jatin Kumar 2015

6
これはまだほとんど意味がありません。マンページでは、+X foo呼び出したときと同じ自動読み込みをfoo実行することのポイントについて説明していますが、すぐに実行することはありません…autoload +X foo && foo完全に冗長に思えます。このパターンを選んだ理由を説明できますか?
ELLIOTTCABLE 2015年

2
@ELLIOTTCABLE実行のポイントは、モジュールが実際に見つかったIFFautoload -U +X bashcompinit && bashcompinitを(のために&&)実行するbashcompinitことです。Normalはautoload foo常にtrueを返します。後で実行しようとするfoo zshは最終的に「関数定義ファイルが見つかりません」と通知します。autoload +Xすぐにエラーが発生します。
FeRD

1
manページには、その時点でまだ多少不明確である、それは私には思える。autoload +Xそれを実行することなく、負荷の関数-である以上よりもautoloadせず、ありません+X。がないと+X、autoload関数をロードしません。後でロードされる関数を参照するものとして名前をマークするだけです。関数が最初に呼び出されるまで、実際のロードは試行されません。名前付き関数が正常に読み込まれるかどうかを確認する場合は、を使用+Xして読み込み手順をすぐに実行する必要があります。
FeRD

4

以下のためのzsh使用:

  • compdef
  • compadd

私の例:

# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun)
_bxrun_methods() {
    grep "^\s*\(function\s\+\)\?__.\+()\s*{.*$" "${1}" | while read line ; do
        echo "$line" | sed "s/()\s*{.*//g" | sed "s/\s*\(function\s\+\)\?__//g"
    done
}
_bxrun_lst() {
    if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then
        for f in /home/ecuomo/projects/bashx/src/actions/* ; do
            if [ -f "${f}" ]; then
                basename "${f}" | sed 's/\..*$//g'
            fi
        done
    fi
    _bxrun_methods "/home/ecuomo/projects/bashx/bxrun"
    _bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh"
}
_bxrun() {
    local cur
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -W '$( _bxrun_lst )' -- $cur  ) )
}
_bxrun_zsh() {
    compadd `_bxrun_lst`
}
if type complete >/dev/null 2>/dev/null; then
    # bash
    complete -F _bxrun bxrun
else if type compdef >/dev/null 2>/dev/null; then
    # zsh
    compdef _bxrun_zsh bxrun
fi; fi

ソース:私のコードhttps://github.com/reduardo7/bashx


1
リンクされたbashxフレームワークの作成者であることを開示する必要があります。
ベン

4

私はAh-My-ZshプラグインマネージャーとしてAntigenを実行しています。同僚が作成したbash完了スクリプトがいくつかあり、単純なでZshにロードしたいと思いましたsource /path/to/completion

AntigenまたはOMZ(わかりにくい)のいずれかが、プラグインから完了スクリプトをロードすることだけに関心があるように思われるため、問題が発生しました。私はついに自動読み込みbashcompinit compinitその後でこれを回避しましたantigen apply。単に自動ロードするだけbashcompinitでは不十分でした。

source ~/.antigen/antigen.zsh
antigen use oh-my-zsh
antigen apply

autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit

source /path/to/bash_completion

抗原は、その作成.zcompdump時にファイル$ANTIGEN_COMPDUMP私のためだったが~/.antigen/.zcompdump

compinitとbashcompinitを再度呼び出すと、次の場所に2番目の.zcompdumpが作成されます。 $HOME/.zcompdump

それはそうです、私がで設定完了を使用することですので、すべての作業を行います/path/to/bash_completion。両方の.zcompdumpファイルを数回削除して、それらが再生成され、機能しているように見えることを確認しました。

タブを完了しようとしたときにエラーがスローされたため、マシンの再起動後に.zcompdumpファイルを数回rmする必要がありましたが、それがこの設定によるものなのか、それとも他の原因によるものなのかわかりません。rm ~/.zcompdump && rm $ANTIGEN_COMPDUMPそして新しいシェルが私のためにそれを修正します。

執筆時点で使用されているバージョン:

Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3

0

@JatinKumarの答えは私を正しい軌道に乗せましたが、complete代わりにを使用する必要がありましたsource。だからすべて一緒に:

autoload -Uz compinit && compinit
autoload -U +X bashcompinit && bashcompinit

complete -C /usr/local/bin/terraform terraform
complete -C /usr/local/aws/bin/aws_completer aws
complete -C /usr/local/bin/az az
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.