web-dev-qa-db-ja.com

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

zshnotに設定するにはどうすればよいのでしょうか。たとえば、次のような名前の数百のファイルのディレクトリがあります。

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

afterワイルドカードに一致するタブ補完を実行できるようにしたいので、

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

これは私が代わりに得るものです:

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

1つのオプションは、TABキーのデフォルトのキーバインディングを置き換えることです。

bindkey "^I" expand-or-complete

bindkey "^I" complete-Word

これは、一致するすべてのファイルに*を展開しませんが、星はそのままにします。このようにして、無限のリストを取り除きますが、それでもグロブ式は完成しません。

これを解決するには、はるかに注意が必要です。独自の完了ウィジェットを作成する必要があります(man zshcompwidを参照)。

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

    zle -C complete-glob menu-complete compglob
    

    これにより、menu-completeのように動作する新しいウィジェットcomplete-globが導入されます。 )そしてシェル関数compglobを使用して一致を生成します。

    [注:メニューの完成を望まない場合は、はるかに基本的なオプションcomplete-Wordまたはlist-choices]

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

    bindkey "^K" complete-glob
    

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

  3. シェル関数compglobを次のように定義します。これにより、実際の作業が実行されます。

    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

6
mpy

それは不可能だと思います。シェルに、実行するファイルを特定するだけでなく、「ワイルドカードの拡張に応じて有効」になりたくないだけでなく、拡張する「最良の」ワイルドカード式をシェルに認識させる必要があります。こちらです。 2番目の部分はNP完全であると思います。

0
hymie

自分が求めているものを完全に取得できる方法はまだわかりませんが、setopt GLOB_COMPLETEを介して少し変更を加えることができます(これは役立つ場合と役に立たない場合があります)(これにより、展開は1つだけで、タブで移動できます...または、その1つだけを編集して*に戻します。これは、少なくとも小さな改善になる可能性があります)。

man zshoptionsman zshcompctlman zshcompwidなどを掘り下げることもできます。 zshの補完はかなり複雑なので、これを行う方法があるのではないかと思います。

また、やや関連する質問にも注意してください。

bashのようにワイルドカードを完成させるためにzshのオートコンプリートを取得するにはどうすればよいですか?

0
lindes-hw