Mehrere Fenster im vi
Die Textpuffer
Statische Puffer
Dynamische Puffer
Laden und Leeren der Puffer
Das Laden geschieht mit den Anführungsstrichen ("). Ein Ladekommando setzt sich immer zusammen aus dem Namen des Puffers und einem Bewegungskommando (delete, yank). Hier eine Reihe Beispiele:
"a5yy kopiert die fünf folgenden Zeilen in den Puffer a.
"A3yy hängt an den Puffer a weitere 3 Zeilen an.
"fy'd kopiert von Cursor bis zur Textmarke d alles in den Puffer f.
Mit so einem Befehl kopiert man immer bis zur Textmarke, die Marke selbst also nicht mehr.
Möchte man die nummerierten Buffer durchsuchen, so geht man folgenderart vor:
Zuerst ruft man den Buffer 1 auf
"1p
Die entsprechende Zeile wird eingefügt. War es das nicht, so entfernt man die Zeile mit
u und wieder holt mit dem ..
Das wird wiederholt, bis die Buffer alle geprüft sind - dann ist der String verloren...
Einzelne Buchstaben oder Wörter werden erst garnicht in die nummerierten Buffer gelegt.
Zum Einfügen werden auch die Anführungsstriche (") benutzt. Im Kommando wird jetzt statt des Bewegungskommandos das Pastekommando (p oder P) gegeben. Das kleine p fügt den Pufferinhalt nach dem Cursor ein, das große P fügt vor dem Cursor ein.
Die Textmarker
Der vi verfügt über 26 Textmarker, die durch die Buchstaben des Alphabets benannt werden. Ein Marker wird mit dem Befehl "m" und der Angabe des Namens gesetzt. Der gewählte Punkt ist dann die Referenz für Bewegungen, Löschen, Kopieren etc.
Beispiele:
ma setzt den Marker a.
Auf diesen kann man sich jetzt bei der Bewegung beziehen:
`a (Akzent) springt genau auf die Marke,
'a (Hochkomma) an den Anfang der Zeile der Marke.
Abkürzungen
Abkürzungen sind sehr einfach und praktisch. Ich will z.B. nicht immer "Dynamic Host Configuration Protocol" ausschreiben. Also setze ich folgenden Befehl ab:
:abbr dhcp Dynamic Host Configuration Protocol
Wenn ich jetzt "dhcp" (mit Leerzeichen davor und dahinter) tippe, dann expandiert der vi das sofort zum langen Wort. Möchte ich jetzt einmal doch nur die 4 Buchstaben "dhcp" schreiben, dann kann ich entweder "dhcp^V" tippen (also d,h,c,p,CTRL-V, Leertaste) oder ich kann mit dem Kommando "unabbr" die Abkürzung zurücksetzen.
Es ist wichtig, sich zu merken, daß bei Abkürzungen der vi auf das Zeichen nach der eingebenen Sequenz wartet.
Mappen von Tasten
Hierbei wird die definierte Sequenz sofort expandiert, und man kann auch komplizierte Macros auf eine Tastenkombination binden. Dazu dient das Kommando "map". Es gibt zwei Möglichkeiten, die verschiedene Modi des vi benutzten.
map funktioniert mit Kommandosequenzen, die im Kommando Mode (also nach einem ESCAPE) eingegeben werden, während map! auf im Textmodus getippte Sequenzen reagiert.
map! - Text Mode
Die Eingabe des folgenden Befehls bringt den vi dazu, die Folge "dhcp" nicht mehr auf den Bildschirm zu bringen, sondern direkt zu ersetzen:
:map! dhcp Dynamic Host Configuration Protocol
Der "map!"-Befehl kann wie gehabt mit "unmap!" wieder aufgehoben werden und mit CTRL-V temporär umgangen werden. Man kann alle aktuellen Mappings durch eingeben von "map!" am Doppelpunkt sehen.
map - Kommando Mode
Wie im vorigen Abschnitt, nur das die definierte Sequenz im Kommando-Mode, also nach einem ESCAPE, benutzt werden muß. Der "map"-Befehl kann wie gehabt mit "unmap" wieder aufgehoben werden und mit CTRL-V temporär umgangen werden. Man kann alle aktuellen Mappings durch eingeben von "map" am Doppelpunkt sehen.
Das .exrc-File
Abkürzungen und Mappings kann man dem VI beim starten mitgeben. Es ist auch möglich, eine ganze Reihe anderer Steuerbefehle mitzugeben - und man kann pro Unterverzeichnis ein spezielles .exrc pflegen (z.B. für HTML und LaTex). So kann man verschiedene, spezialisierte VI-Instanzen laufen lassen. Über die Umgebungsvariable EXINIT kann bestimmt werden, wie der VI starten soll. Es ist auch jederzeit möglich, ein vorhandenes .exrc einzulesen:
:so .xxxx
Hier ein Beispiel .exrc:
" Ein KommentarDie Syntax ist eigentlich selbsterklärend, und zu den Macros kommen wir jetzt.
set noautoindent
set showmode
set tabstop=8
...
ab c <>
ab _c < /CENTER>
ab hf < href="">
...
" Ein Macro:
" CTRL X Nummer: H1 bis H2 (1-2)
map ^X1 I<>^A< /H1> ^[D^[o
map ^X2 I<>^A< /H2> ^[D^[o
...
Macros
Das schreiben von Macros ist eigentlich sehr einfach, da es sich um Abfolgen von vi-Befehlen handelt, die man normalerweise auch so Absetzen kann. Aufgrund der Struktur der Buffer ist es innerhalb eines Macros zusätzlich möglich, Dinge zeitlich zu versetzen, also eine Eingabe zu machen, die erst nach der Eingabe an die richtige Stelle kopiert wird.
Die große Gefahr sind recursive macros, also Macros, die sich selbst während ihrer Ausführung erneut aufrufen. Ein Beispiel wäre folgendes Mapping: map! dhcp Das dhcp klasse sein. Hier ruft das Macro sich selbst auf und es kommt zur Katatrophe. Daher ist man gut beraten, wenn man sich seine Macros vorher gut anschaut und gründlich testet, bevor man sie eingibt oder im .exrc verewigt.
Hier einige nützliche Beispiele - der Fantasie sind keine Grenzen gesetzt. In den Macros müssen eine Reihe Steuersequenzen eingesetzt werden. Diese werden mit der CTRL-Taste (STRG-Taste) erzeugt. So ist ^X die Kombination CTRL-X etc. Ein spezieller Fall ist die Escape-Sequenz ^[, die man mit der Kombination CTRL-V und dann ESCAPE-Taste erhält. Da es Stuerzeichen sind, ist es nicht möglich, eine solche Zeile z.B. mit der Maus zu kopieren (greppen), da die Steuerzeichen verloren gehen.
map ^X1 I<>^A< /H1> ^[D^[o
Hier ist definiert, das die Tastenkombination CTRL-X auf einer gerade geschriebenen Zeile folgende Aktionen auslöst: Es wird am Anfang der Zeile die Header-1 Anweisung eingefügt, am Ende ausgeführt, bis zum Zeilenende gelöscht und eine neue Zeile zur Eingabe geöffnet.
map ^X^L o< /A>^[kO">^[I< href="">
Die Kombination CTRL-x + w führt dazu, das der unter dem Cursor liegende Text in eine HREF... Anweisung eingeführt wird. Der Cursor springt dann noch zur richtigen Stelle zur Eingabe des Links (URL).
map ^X^W a< /A>^[bbbi< href="http://#">^[F#
Dasselbe für ein Wort (statt der ganzen Zeile).
Man kann Macros verketten - dazu dient der "=" Befehl. Damit ist es möglich, einige ärgerliche Begrenzungen bezüglich der Länge eines Macros zu überwinden.
Einfaches umbennen vieler Files
Der vi ist auch sehr praktisch beim Bearbeiten großer Mengen an Files, z.B. wenn man 1000 Files "name.txt" nach " name.html" umbenennen möchte:
Man öffnet den vi und geht in den Colon Mode:
:r !ls *.txt # xyz.txt
:%s/.*/mv & &/ # mv xyz.txt xyz.txt
:%s/txt$/html/ # mv xyz.txt xyz.html
:w !sh
:q!
In der ersten Anweisung liest der vi ein Listing des Inhalts des Direktories ein. Das kann man natürlich auch noch editieren. Die zweite Anweisung sagt dem vi, den ganzen Ausdruck (.*) durch "mv & &" zu ersetzen. Der Ampersand steht dabei für den Ausdruck, der mit ".*" in den Buffer geschrieben wurde. Jetzt wird "txt" durch "html" ersetzt, und zwar nur, wenn es am Ende der Zeile steht, daher das "$". Man kann nun die Sache nochmal checken. Mit der Write-Anweisung schreibt man das Ergebnis nicht in ein File, sondern auf eine Shell, die jede Zeile als Kommando interpretiert und ausführt.
Das sieht im Beispiel so aus:
Im VI, nach einlesen mit ":r !ls *":
plautze1.jpgHier der Befehl, der folgende Zeile erzeugt:
plautze2.jpg
plautze3.jpg
plautze4.jpg
plautze5.jpg
Das ist das File plautze*.jpg ...
:.,5s/.*/Das ist das File & .../
Jetzt hat man oft das Problem, daß man am Filenamen etwas ändern möchte, was nicht am Ende steht. Zb. sollen alle Files sapPEUvg3.out nach sapGAGvg3.out umbenannt werden. Man erzeugt also wie oben folgende vi-Datei:
mv sapPEUvg0.out sapPEUvg0.outJetzt muß man das zweite PEU jeder Zeile in GAG umschreiben; das macht einen Trick nötig, da vi die Zeilen von links nach rechts durchgeht. Daher kann man entweder jeweils die erste Instanz ändern, oder alle. Man ändert also alle PEU in einer Zeile in GAG, und ändert dann das erste GAG in PEU zurück:
mv sapPEUvg1.out sapPEUvg1.out
mv sapPEUvg2.out sapPEUvg2.out
mv sapPEUvg3.out sapPEUvg3.out
:%s/PEU/GAG/g ==> alle Namen haben jetzt das GAG.Man kann auch richtig professionel vorgehen und zuerst das erste PEU in GAG umbenennen und dann die Worte tauschen:
:%s/GAG/PEU/ ==> nur das jeweils erste GAG auf der Zeile wird zum PEU.
g/GAG/s/^\([^ ]*\) \([^ ]*\) \([^ ]*\)/\1 \3 \2/Das vertauscht auf jeder Zeile, die "GAG" enthält, das zweite mit dem dritten Wort; man erhält das gewünschte File und kann die Files umbennen.
Wenn man weiss, was man tut, dann kann man sich den Umweg über den vi sparen:
ls -d *.xxx | sed "s/.*\)\.xxx$/mv '&# '\1.old'/" | sh
Macht aus File bla.xxx das File bla.old.
ls -d | sed "s/[A-Z,a-z,0-9,.,_,-]*/mv '&' '&.html'/" | sh