Platzhalter bei der Tab-Vervollständigung nicht erweitern

Platzhalter bei der Tab-Vervollständigung nicht erweitern

Ich frage mich, wie ich konfigurieren kannzshZunichtErweitern Sie das Platzhalterzeichen in einem Dateinamen. Ich habe beispielsweise ein Verzeichnis mit einigen hundert Dateien, das wie folgt heißt:

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

Ich möchte eine Tab-Vervollständigung durchführen könnennachein Platzhalter, also

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

Das ist, was ich stattdessen bekomme:

$ Katze *.foo-
=> Katze a.foo-bar
   Datei
   a.foo-bar b.foo-bar c.foo-bar

Antwort1

Eine Möglichkeit besteht darin, dass Sie die Standardtastenbelegung für die TABTaste ersetzen

bindkey "^I" expand-or-complete

mit

bindkey "^I" complete-word

Dadurch wird a nicht *auf alle passenden Dateien erweitert, sondern der Stern bleibt unberührt. Auf diese Weise werden Sie die endlose Liste los, aber der Globbing-Ausdruck wird dadurch immer noch nicht vervollständigt.

Dies zu lösen ist viel schwieriger. Sie müssen Ihre eigeneVervollständigungs-Widget(sehen man zshcompwid).

  1. Beginnen wir mit der Definition:

    zle -C complete-glob menu-complete compglob
    

    Dies stellt das neue Widget vorKompletter Glob, das sich verhält wieMenü komplettund verwendet dieShell-Funktion kompglobum die Übereinstimmungen zu generieren.

    [ Hinweis: Wenn Sie die Menüvervollständigung nicht wünschen, verwenden Sie die viel rudimentäreren Optionenvollständiges WortoderListenauswahl]

  2. Binden Sie dieses neue Widget an eine praktische Verknüpfung, etwa CTRL+K:

    bindkey "^K" complete-glob
    

    Binden Sie dies nicht an TAB, da das Widget in seiner aktuellen Form nur Dateien vervollständigt!

  3. Definieren Sie die Shell-Funktionkompglobwie folgt, das die eigentliche Arbeit erledigt:

    compglob () {
        setopt localoptions globsubst
        compset -P '*'
        files=(${IPREFIX}*) 
        display=(${files/${IPREFIX}/${(q)IPREFIX}}) 
        glob=(${files/${IPREFIX}/}) 
        compadd -d display -- $glob
    }
    
  4. Demonstration:

    $ 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
    

    Der einzige Fehler, den ich sehe, ist das \vor dem Stern in der angezeigten Liste. Dies ist jedoch nur ein optischer Fehler, da die Vervollständigung korrekt ist: *.foooder *.foo-bar.

Antwort2

Ich glaube nicht, dass das möglich ist. Sie verlangen von der Shell nicht nur, herauszufinden, welche Dateien Sie als „gültig gemäß Ihrer Platzhaltererweiterung“ ansehen möchten und welche nicht, sondern Sie möchten, dass die Shell den „besten“ Platzhalterausdruck findet, der auf diese Weise erweitert wird. Ich würde erwarten, dass der zweite Teil NP-vollständig ist.

Antwort3

Ich sehe noch keine Möglichkeit, wie Sie genau das bekommen, wonach Sie suchen, aber Sie können eine kleine Modifikation erhalten (die für Sie hilfreich sein kann, aber nicht muss) über setopt GLOB_COMPLETE(dies gibt Ihnen nur eine Erweiterung und Sie können sie dann durchgehen ... oder nur diese eine bearbeiten, sodass sie *wieder eine ist, was zumindest eine kleine Verbesserung sein kann).

man zshoptionsSie können auch in , man zshcompctl, und/oder Ähnlichem herumstöbern man zshcompwid. Die Vervollständigung für zsh ist ziemlich komplex, daher vermute ich, dass es durchaus eine Möglichkeit geben könnte, dies zu tun.

Beachten Sie auch eine etwas damit zusammenhängende Frage:

Wie erreiche ich, dass die Autovervollständigung von zsh Platzhalter vervollständigt, wie es bei Bash der Fall ist?

verwandte Informationen