Neue Z Shell Vervollständigung mit compsys
Zuletzt editiert am: Do Apr 1 09:57:40 CEST 2004
Die Zsh besitzt seit ein paar Jahren einen neuartigen, Funktionen basierten
Vervollständigungsmechanismus der Kommandozeile, der sehr weitgreifende
Vervollständigungen
samt dem Einsatz von Kommentaren in der Vervollständigung möglich
macht.
Mit autoload -U compinit && compinit wird dieser
neue Mechanismus wirksam, was man in der Datei .zshrc eintragen
sollte.
Jetzt sind über 440 mitgelieferte Funktionen verfügbar, die alle mit
einem
Unterstrich (_) beginnen und mit compdef _funktion
kommandoname einem beliebigen Befehl zugeordnet werden können.
Das Besondere an diesem Z-Shell basiertem Mechanismus ist die fast unübersichtlich
erscheinene Fülle der Möglichkeiten, auf die Vervollständigungen
einzuwirken. Der "Stil", nach dem die ZShell vorgeht, läßt sich
dabei sehr weitgehend dem eigenen Geschmack anpassen mittels
zstyle (siehe man zshcompsys | less -p "* zstyle
.*$" ).
Beispiele für die Verwendung von compdef
- Der einfachste aber auch banalste Weg zur Vervollständigung mit einer
eigenen Funktion geht mit dem Befehl "compadd".
_banal() { compadd eins zwei drei vier fuenf ; }
Die Funktion muß einen Unterstrich als Anfang besitzen. Hat man die
Funktion definiert, dann wird sie nun durch compdef _banal
befehl
verwendbar.
-
Ohne viel Programmiererei läßt sich die schon vorhandene Funktion
_gnu_generic zum Vervollständigen von Programmen, die die
GNU-Option "--"
nutzen, gebrauchen. Gedacht waren die langen Optionsnamen mit "--"
für eine explizitere Beschreibung einer Option eines Programms. Da aber
zusätzlich auch immer noch die Möglichkeit bestehen bleiben sollte,
verschiedene Flags kombiniert zu einem einzelnen Wort nach einem '-' anzugeben,
wählte man das
"--" als eindeutiges Zeichen und konnte so alten Stil und neuen Stil bei einem
Konsole-Aufruf weiterverwenden. Dass aber der neue GNU-Stil so wenig benutzt
wird, liegt einfach daran, dass er so schreibintensiv ist. Hier kann nun die
Funktion _gnu_generic Abhilfe schaffen. Man spart sich das Gucken ins
Manual oder den erneuten Aufruf von "--help".
compdef _gnu_generic tail head gpg kann beispielsweise
benutzt werden, um den Befehlen tail, head und gpg nach
"--" lange Optionsnamen mitzugeben. Es erscheint
dann eine Auswahl. Man gucke sich einmal die Ausgabe von gpg
-- nach Eingabe des zuletzt genannten Befehls an.
Das ganze Vervollständigungsgeheimnis liegt hier in der Funktion
_gnu_generic, die bei allen
GNU-Programmen, die --help unterstützen, versucht, die Argumente mit
langen Optionen zu ermitteln.
-
Mit
compdef '_files -g "*.log"' programm kann man
programm alle *.log Dateien und Ordner ergänzen lassen. Das -g bezieht
sich dabei auf globbing. Der Stern steht dann für eine beliebige Anzahl
von Buchstaben.
Vervollständigung in Farbe
Mit Hilfe von Ansi-Escapes-Codes war es schon sehr lange möglich, Farbe in
das Konsolenleben und in Skripte zu bringen. Der allgemeine Mechanismus wird
sehr gut in
diesem
Artikel von Nico Golde mit Schwerpunkt Bash beschrieben.
Bei der Zsh kann man auch in die Vervollständigung Farbe bringen:
Dazu lädt man das complist-Module durch zmodload
zsh/complist dazu und definiert mit Hilfe von
zstyle einen Vervollständigungsstil.
Die Syntax ist leider etwas kompliziert, nichts desto trotz aber sehr
mächtig.
Im nächsten Beispiel muss extendedglob mit 'setopt extendedglob' gesetzt
sein:
zstyle ':completion:*:*:tar:*:values' list-colors '=(#b)([A-z]) #(--)*=37=31=32'.
Problem dieser Definition ist die Menge an Informationen auf einer Zeile.
Deshalb schlage ich vor, Variablen zu definieren und dann zu benutzen.
zstyle ":completion:*:*:$kommando:*:$tag" list-colors \
"=$zshregex=$standard-farbzahl=$klammer1_farbzahl=$klammer2_farbzahl"
könnte man vielleicht als eine Rohform für eine 3farbige Vervollständigungsform benutzen. Man muss dann nur noch alle Variablen definieren.
Wie man nun sehen kann, ist der erste Teil nach "list-colors" der reguläre
Ausdruck, dem ein `=' vorausgeht. Dieser reguläre Ausdruck bestimmt, was
eingefärbt wird. Nach dem regulären Ausdruck kommt wieder
ein Gleichheitszeichen, danach die Standard-Farben-Nummer, die ohne eine
genauere Spezifizierung als Standardfarbe benutzt werden soll. Hierauf folgt
wieder ein Gleichheitszeichen, jetzt die Farbnummer für die Worte der
ersten Klammer und nach einem weiteren `=' wieder eine Farbnummer f¨r die
zweite Klammer.
Auf den regulären Ausdruck muss ich genauer eingehen:
(#b)ist nicht Teil dessen, was gesucht ist, sondern
ermöglicht erst das Benutzen von Klammern, um dadurch
Teile verschieden einzufärben. Alles, was in Klammern danach steht, kann
eine
unterschiedliche Farbe besitzen. So ist die $klammer1_farbe
eigentlich das erste Klammern-Paar nach (#b),
insgesamt also das
zweite, da ja (#b) nicht mitzuzählen ist.
Statt Ansi-Farbzahlen wie 31, 32 und 37 kann man auch eine vordefinierte
Farbvariable mit einer Zeichenkette als Index (=assoziatives Array) nutzen. Dazu
bindet man mit autoload colors die Variable colors ein.
Im Beispiel bedeutet #: "Suche nach 0 oder mehr Leerzeichen", es
ist also wie auch das # in (#b) kein
Kommentarzeichen!!!
zstyle ':completion:*:*:tar:*:values' list-colors "=(#b)([A-z]) #(--)*=$color[white]=$color[red]=$color[green]"
Andere Quellen der Information
Writing Completion Functions-Linux Magazine