タブ補完時にワイルドカードを展開しない

タブ補完時にワイルドカードを展開しない

どのように設定すればよいのか知りたいのですが翻訳ないファイル名のワイルドカードを展開します。たとえば、次のような名前の数百個のファイルがあるディレクトリがあります。

a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo

タブ補完マッチングを実行できるようにしたいワイルドカードなので

cat *.foo-< tab > => cat *.foo-bar

代わりに次のものが表示されます:

$ cat *.foo-
=> cat a.foo-bar
   ファイル
   a.foo-バー b.foo-バー c.foo-バー

答え1

TAB1つの選択肢は、キーのデフォルトのキーバインディングを置き換えることです

bindkey "^I" expand-or-complete

bindkey "^I" complete-word

これは、*一致するすべてのファイルに a を展開するのではなく、星印をそのまま残します。この方法では、無限リストはなくなりますが、それでもグロブ表現は完了しません。

これを解決するのはもっと難しい。自分で書かなければならない。完了ウィジェット(見るman zshcompwid)。

  1. 定義から始めましょう:

    zle -C complete-glob menu-complete compglob
    

    これは新しいウィジェットを紹介します完全なグロブのように動作しますメニュー完了そして、シェル関数 コンプグロブ一致を生成します。

    [注: メニュー補完が不要な場合は、より基本的なオプションを使用してください。完全な単語またはリストの選択肢]

  2. この新しいウィジェットを、次のような便利なショートカットにバインドしますCTRL+K

    bindkey "^K" complete-glob
    

    TAB現在の形式のウィジェットはファイルを補完するだけなので、これを にバインドしないでください。

  3. シェル関数を定義するコンプグロブ実際の作業は次のようになります。

    compglob () {
        setopt localoptions globsubst
        compset -P '*'
        files=(${IPREFIX}*) 
        display=(${files/${IPREFIX}/${(q)IPREFIX}}) 
        glob=(${files/${IPREFIX}/}) 
        compadd -d display -- $glob
    }
    
  4. デモンストレーション:

    $ touch a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo
    $ cat *.f<CTRL+K>
    $ cat *.foo
    \*.foo      \*.foo-bar
    

    私が見つけた唯一の欠陥は、\提示されたリストの星の前の です。しかし、これは単なる視覚的な欠陥であり、完成形は正しいです:*.fooまたは*.foo-bar

答え2

それは不可能だと思います。シェルに、ワイルドカード拡張に従って有効にするファイルと無効にするファイルを判別するだけでなく、このように拡張する「最適な」ワイルドカード式を判別するように要求しているのです。2 番目の部分は NP 完全であると思います。

答え3

今のところ、あなたが求めているものを完全に実現する方法は見当たりませんが、 (setopt GLOB_COMPLETEこれにより 1 つの拡張のみが提供され、タブでそれらを移動できます... または、その 1 つだけを編集して*再度 にすると、少なくとも少しは改善される可能性があります) を介して、少し変更することができます(役立つ場合と役立たない場合があります)。

man zshoptionsまた、、man zshcompctlおよび/または同様のものを調べてみることもできますman zshcompwid。zsh の補完機能は非常に複雑なので、これを行う方法があるのではないかと思います。

また、多少関連する質問にも注意してください:

zsh のオートコンプリートで bash のようにワイルドカードを補完するにはどうすればよいですか?

関連情報