web-dev-qa-db-ja.com

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

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

74
Coderer

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

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

34
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file
139
freestyler
_autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script
_

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

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


上記の3行の詳細については、以下を参照してください。

Bashには自動補完のサポートが組み込まれていますが、zsh環境にはcompgencompleteなどの基本的なbash自動補完ヘルパー関数がないため、bash自動補完スクリプトはzshで直接動作しません。これは、zshセッションを高速に保つために行われます。

最近のzshには、bash自動補完スクリプトをサポートするために必要な機能を備えたcompinitbashcompinitなどの適切な完了スクリプトが付属しています。

_autoload <func_name>_:autoloadは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オートコンプリートや独自の_~/.zshrc_などの他のスクリプトが_autoload -U +X compinit && compinit_を実行している可能性があるためですが、両方を実行するだけで安全です.

31
Jatin Kumar

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

2
Eduardo Cuomo

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

AntigenまたはOMZ(わかりにくい)のどちらかが、プラグインからの完了スクリプトの読み込みのみに関心があるように見えるため、私はいくつかの問題を抱えていました。私はついにbashcompinitandcompinitantigen 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

Antigenは.zcompdumpファイルを$ANTIGEN_COMPDUMPに作成します。これは私にとっては~/.antigen/.zcompdump

Compinitとbashcompinitを再起動すると、$HOME/.zcompdumpに2番目の.zcompdumpが作成されます

それは、seemsがすべてうまくいくからです。なぜなら、/path/to/bash_completionによって設定された補完を使用できるからです。両方の.zcompdumpファイルを数回削除して、それらが再生成されて機能していることを確認しました。

Tab Completeを試みるときにエラーがスローされるため、マシンのリブート後に数回.zcompdumpファイルをrmしなければなりませんでしたが、これがこの設定によるものなのか、他の原因によるのかはわかりません。 rm ~/.zcompdump && rm $ANTIGEN_COMPDUMPおよび新しいシェルがそれを修正します。

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

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