等号の後にパスを自動補完するbash補完スクリプトを作成しますか?


11

フォーム--argとの引数を認識するbash補完スクリプトを作成したいと思います--some-arg=file

このチュートリアルといくつかの例を読んだ後/usr/share/bash_completion/completions/、次のスクリプトを作成しました(Chromiumでいくつかのフラグを入力する時間を節約するため)。

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=file
    if [[ ${cur} == "--"*"=" ]] ; then
        # Removed failures (is my logic OK?)
        return 0
    fi

    # Handle other options
    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _chromium chromium

それをに保存し~/bash_completions/chromium、を使用してシンボリックリンクを作成しましたsudo ln -s ~/bash_completions/chromium /usr/share/bash_completion/completions/chromium
次に、を使用してそれをロードしました. /usr/share/bash_completions/completions/chromium

現在、2つの問題が発生しています。

  • chromium --u<TAB>展開しますchromium --user-data-dir=<SPACE>(スペースは必要ありません)。
  • パス(ディレクトリとファイル)はもう完了していません。

これらの問題を解決するにはどうすればよいですか?


zshへの切り替えはオプションですか?
Gilles「SO-悪をやめなさい」

回答:


11

私は両方の問題の解決策を見つけました!

  1. スペースを追加しない場合は、nospaceオプションを使用します。これは2つの方法で実行できます。

    • に渡しますcomplete
      complete -o nospace -F _chromium chromium
    • compopt組み込みを使用:(
      compopt -o nospaceオプションを有効にするため)
      compopt +o nospace(オプションを無効にするため)

    私はそれをgnu.orgのBashのドキュメント、8.7 Programmable Completion Builtinsで見つけました。

  2. ファイルの完成。
    • peterphはで-fフラグを使用すること提案しましたcompgen。私はそのアドバイスに従い、それをとして実装しましたCOMPREPLY=( $(compgen -f "$cur") )。スペースを含むパスを完成させようとするまで、これはうまくいきました。
      Stack Overflow で、完了リストを手動で作成することを推奨するこの回答を見つけました(を使用せずにcompgen)。このアプローチはうまくいきました。
    • filenamesオプションを使用して、compspecがファイル名を生成することをReadlineに伝え、次のことができるようにします。
      • ファイル名固有の処理(ディレクトリ名へのスラッシュの追加、特殊文字の引用、末尾のスペースの抑制など)を実行する
      • 異なる色を使用してファイルの種類を示します(colored-stats有効)

助けを借りてバッシュの文字列操作(拡大する~とスペースを扱う)、私が質問に記載されたすべての基準を満たしているのbash補完スクリプトを構築しました。

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=
    if [[ ${prev} == "--"* && ${cur} == "=" ]] ; then
        compopt -o filenames
        COMPREPLY=(*)
        return 0
    fi
    # Handle --xxxxx=path
    if [[ ${prev} == '=' ]] ; then
        # Unescape space
        cur=${cur//\\ / }
        # Expand tilder to $HOME
        [[ ${cur} == "~/"* ]] && cur=${cur/\~/$HOME}
        # Show completion if path exist (and escape spaces)
        compopt -o filenames
        local files=("${cur}"*)
        [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]// /\ }" )
        return 0
    fi

    # Handle other options
    COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
    if [[ ${#COMPREPLY[@]} == 1 && ${COMPREPLY[0]} != "--"*"=" ]] ; then
        # If there's only one option, without =, then allow a space
        compopt +o nospace
    fi
    return 0
}
complete -o nospace -F _chromium chromium

素晴らしい回答、ありがとうございました。私の時間を大幅に節約できました。-fファイルパスの補完にスイッチを使用しまし/たが、それがディレクトリの場合、char は補完されません...それは小さなことです。
Jiri Kremser 2014年

1

ファイル名を完成させるには、に渡し-fてみてくださいcompgen

オプションの後にスペースを削除することはできません。これは補完の仕組みです。一意の一致が見つかると、完全に補完されます。


の提案をありがとう-f。試してみましたが、スペースが正しく処理されません。パスの/tmp/foo bar結果、2つの補完エントリ/tmp/fooとが生成されbarます。不要なものについて--arg=<SPACE>:私はその解決策を見つけ、以下の回答に投稿しまし
Rob W
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.