UNIX-Editoren vi und emacs
|
Willemers Informatik-Ecke
Da unter UNX fast alle Konfigurationen über Textdateien laufen, ist ein
guter Editor ein wichtiges Werkzeug.
In Zeiten der grafischen Oberflächen wirkt die Bedienung auf manchen
Einsteiger etwas
archaisch. Der vi existiet nicht nur aus Gewohnheit auf UNIX-Systemen,
sondern weil er gerade durch sein ungewöhnliches Konzept auch ungewöhnlich
leistungsfähig ist. Zugegebenermaßen erschließen sich die Fähigkeiten
nicht auf Anhieb.
Der Editor vi ist sehr verbreitet. Man findet ihn nicht nur auf
jeder UNIX Maschine, sondern auf diversen anderen Plattformen auch.
Neben oder statt des originalen vi werkelt oft ein Clone, der
nicht selten einige Erweiterungen erfahren hat. Die bekanntesten Vertreter
sind elvis und vim.
Der vi hat ein originelles Konzept, dessen Vorteile nicht auf Anhieb
erkennbar sind. Es gibt drei Modi, in denen sich das Programm befinden kann:
den Kommandomodus, den Eingabemodus und den Befehlsmodus.
Kommandomodus
Nach dem Starten des vi befindet man sich im Kommandomodus.
Hier kann man im Text positionieren, suchen und Kommandos zur Textveränderung
geben. Durch solche Kommandos gelangt man in den Eingabemodus.
Eingabemodus
Der Eingabemodus ist recht simpel. Man kann Text eingeben und mit der
Korrekturtaste (Backspace) die letzten Vertipper innerhalb der aktuellen
Zeile korrigieren. Alle anderen Korrekturen und Maßnahmen werden vom
Kommandomodus aus erledigt, in den man durch die Taste ESC1)
wieder zurückkehrt.
Befehlsmodus
Vom Kommandomodus aus erreicht man durch Eingabe des Doppelpunktes den
Befehlsmodus. Der Cursor geht in die unterste Zeile und erwartet einen durch
Return abgeschlossenen Befehl. Diese Befehle entsprechen übrigens zum Teil
denen des sed. Sie betreffen
in erster Linie den Text als Ganzes, beispielsweise das Sichern und Wechseln
von Texten.
Kommandomodus (Navigation im Text) |
zum Eingabemodus: i, a, cx, R |
zum Kommandomodus: ESC |
zum Befehlsmodus: : |
zum Kommandomodus: ESC |
Eingabemodus |
Befehlsmodus |
Die Abbildung zeigt die Modi des vi im Überblick. Nachdem man den vi gestartet
hat, befindet man sich im Kommandomodus, in dem auch durch den Text navigiert
wird. Cursorpositionierung, Blättern und Suchen findet hier statt. Mit
Kommandos wie i (insert), a (append), cx (Das x
steht hier für ein Zeichen, das den Bereich bestimmt, auf den die Änderung
wirken soll.) (change) und R (replace)
gelangt man an der aktuellen Position
in den Eingabemodus. Dort gibt man Text ein. Ist die Eingabe soweit
abgeschlossen, kehrt man mit ESC wieder zurück in den Kommandomodus, um
zur nächsten Stelle zu navigieren. Vom Kommandomodus gelangt man mit dem Doppelpunkt
in den Befehlsmodus. Hier gibt man unter anderem die Befehle zum Verlassen,
zum Sichern und Hinzuladen.
Verlassen
Das wichtigste zuerst: man kommt aus vi heraus, indem man zunächst ggf. den
Editiermodus verlässt. Das geschieht durch ESC. Falls ein ESC zuviel gedrückt
wurde, piept vi. Aber das stört eigentlich nur die Akustik.
:q
Dann wechselt man mit dem Doppelpunkt in den Befehlsmodus. Der Cursor geht in
die letzte Zeile. Als Befehl gibt man ein einfaches, kleines q (quit) ein und
bestätigt mit der Returntaste. Sollte vi nörgeln, dass Änderungen noch nicht
gesichert sind, kann man dies mit :q! ignorieren oder mit :wq
(write quit) vor dem Verlassen sichern.
| Befehl | Wirkung |
| ESC :q | verlassen von vi |
| ESC :q! | verlassen von vi und verwerfen aller Änderungen |
| ESC :wq | verlassen von vi und vorheriges Sichern unter dem bisherigen Namen |
Starten des vi
Die Arbeitsdatei beim Start nennen
Wollen Sie eine Datei erstellen, geben Sie vi gefolgt von dem Namen der neuen
Datei an. Sie landen in einem Bildschirm, auf dem alle Zeilen mit einer Tilde
beginnnen. Am Ende des Bildschirms steht der Name der Datei und die Position.
Das Tildezeichen soll anzeigen, dass das Ende des Textes erreicht ist. Um
etwas einzugeben, tippen Sie ein kleines i (insert). Sie sehen an der Statuszeile,
dass vi in den Einfügemodus gewechselt hat. Sie können nun Text von einigen
Zeilen eingeben, Tippfehler sollten Sie zunächst ignorieren. Ist der Text
eingegeben, erreichen Sie mit ESC wieder in den Kommandomodus. Nun sollten
Sie den Text sichern, indem Sie mit einem Doppelpunkt in den Befehlsmodus
wechseln. Geben Sie w (write) ein und der Text wird gesichert. Als Dateiname
wird derjenige verwandt, den Sie beim Start von vi angaben. Man kann nun
vi wieder mit :q verlassen.
Grundlegende Navigation
Sie können die Datei wieder bearbeiten, indem Sie den vi wieder mit dem
Dateinamen starten. Nun sehen Sie den Text im Überblick und befinden sich
wieder im Kommandomodus. Zunächst bewegen Sie sich an die Stelle, wo Sie
etwas ändern wollen. Mit + und - können Sie zeilenweise auf und ab gehen.
Mit Leertaste und Backspace können Sie nach links und rechts in der Zeile
über den Text fahren. Auf vielen Systemen arbeiten auch die Cursortasten. Haben
Sie die Zielstelle erreicht, können Sie wieder mit i neuen Text hinzufügen
oder mit kleinem x (wie extract oder wie eine kleine Schere) einzelne Zeichen
unter dem Cursor löschen. Zwei Zeilen kann
man mit einem großen J (join) zusammenfügen. Mit diesen Kommandos kommt man bereits
sicher durch den vi, auch wenn das noch nicht sehr komfortabel ist.
Bewegungen durch den Text im Kommandomodus
Auf den meisten Systemen funktionieren die Standardtasten für die
Cursorbewegungen.
Das wird den meisten Anwendern am einfachsten erscheinen. Leider ist funktioniert
das im Allgemeinen nur auf dem lokalen Rechner. Sobald man mit Hilfe des Netzes
auf fernen Rechnern arbeitet (siehe telnet),
hat man es mit Terminalemulationen zu tun, bei denen oft die Funktionstasten
nicht mehr funktionieren. In solchen Fällen arbeiten aber immer noch die normalen
Tasten und die ctrl-Kombinationen. Insofern ist es hilfreich, dass vi auch mit
diesen Tasten bedienbar ist.
| Weite | zurück | vor |
| Ein Zeichen | h oder Backspace | Leertaste |
| Ein Wort | b | w |
| Zeilenanfang/-ende | ^ | $ |
| an die n-te Spaltenposition | | n| |
| Zeile | - | + |
| Seite | ctrl-F | ctrl-B |
| zur Zeile n | nG | |
| Textanfang/-ende | 1G | G |
Suchen im Text
Suchen: /
vi sucht mit dem Schrägstrich. Daraufhin geht der Cursor in die unterste Zeile und man gibt den Suchbegriff ein und bestätigt mit Return. Um das nächste Erscheinen des gleichen Begriffs zu suchen, gibt man ein kleines n ein. Mit einem großen N kommt man zum vorherliegenden Erscheinen des Begriffs.
Will man von vornherein rückwärts suchen, verwendet man das Fragezeichen
statt dem Schrägstrich als Befehl. Auch hier arbeiten n und N, allerdings
jetzt in der anderen Richtung.
Editieren
Um den Text zu bearbeiten, wird man zunächst Text einfügen. Dazu gibt es aus
folgende Kommandos:
| Taste | Wirkung |
| i | einfügen (engl. insert) an der Cursorstelle |
| I | einfügen vor dem ersten Wort der Zeile |
| a | hinter der Cursorstelle einfügen (engl. append) |
| A | an das Ende der Zeile anhängen |
Die Eingaben werden durch ESC bestätigt.
Man kann statt dem Einfügen auch existierenden Text ersetzen. Dabei dient das
c als Zeichen für Change. Es folgt ein Zeichen, was man ersetzen will. Hier
heißt w Wort, $ bis Zeilenende, l ein Zeichen oder die Verdoppelung des c
für die ganze Zeile.
Auf dem Bildschirm wird der Ausschnitt, den man ersetzt, durch ein
Dollarzeichen begrenzt.
| Tasten | Wirkungsbereich |
| cw | Wort |
| c$ | bis Ende der Zeile |
| cc | aktuelle Zeile |
| cl oder r | Zeichen |
| R | geht in den Überschreibmodus bis zum ESC |
Mehrfache Ausführung
Durch das Voranstellen von Zahlen lassen sich diese Befehle vervielfältigen. So
ersetzt beispielsweise 5cw die nächsten 5 Worte durch das, was man bis zum
ESC eingibt. Durch Eingabe eines Punktes ist dies an anderer Stelle wiederholbar.
Löschen und Kopieren
Das Kommando zum Löschen von Textteilen beginnt mit d (für engl. delete).
Wie beim Ändern wird die Weite des Löschens durch den zweiten Buchstaben bestimmt,
dabei gilt w für ein Wort, $ bis zum Ende der Zeile und die Verdoppelung des
Kommandobuchstaben betrifft die komplette Zeile. Für den Buchstaben wird
das l verwendet, aber es gibt auch hier einen extra Buchstaben.
| Tasten | Wirkungsbereich |
| dw | Wort |
| d$ | bis Ende der Zeile |
| dd | aktuelle Zeile |
| dl oder x | Zeichen |
Löschen bis Suchkriterium
Man kann durch Verwendung der Suchfunktion das Ziel angeben, bis wohin
gelöscht werden soll. Start ist die aktuelle Cursorposition. Beispiel: d/abc
Returntaste löscht alles zwischen hier und dem nächsten Auftreten der
Zeichenkette abc.
Der Puffer
Die gelöschten Textbereiche werden in einem Puffer zwischengelagert. Dieser
Puffer kann jederzeit an jeder Stelle mit p oder P wieder hervorgebracht werden. Dabei ist p hinter und P an der aktuellen Cursorposition
Man kann den Puffer allerdings auch füllen, ohne das Original zu löschen. Man verwendet lediglich das Kommando y (yank) statt d.
| Tasten | Wirkungsbereich |
| yw | Wort |
| y$ | bis Ende der Zeile |
| yy | aktuelle Zeile |
Zeilenvorschub löschen
J vereinigt Zeilen.
Um zwei Zeilen aneinander zu hängen, also den Zeilenvorschub der oberen Zeile zu löschen, geht man in die obere Zeile und gibt ein großes J ein. Die beiden Zeilen werden vereinigt und dazwischen steht ein Leerzeichen.
Geklammerte Bereiche
% als Bereich zwischen Klammern
Für Programmierer besonders interessant ist der Umgang mit Klammern. Man
positioniert den Cursor auf einer Klammer und vi springt durch das %-Zeichen
auf die korrespondierende Klammer. Dabei werden runde, eckige und geschweifte
Klammern akzeptiert. Das Prozentzeichen kann man auch als Bereichsangabe anderer
Befehle verwenden. Die Tastenkombination d% löscht den Bereich von der
aktuellen Klammer unter dem Cursor bis zum korrespondierenden Klammer.
Einrücken
Besonders interessant ist das Einrücken in Verbindung mit Klammerungen für
C-Programmierer. Man kann sich auf eine geschweifte Klammer stellen und durch
das Kommando >% den kompletten Block um so viele Leerzeichen einrücken, wie
in der Variablen shiftwidth definiert ist.
| Tasten | Wirkung |
| % | springe von dieser Klammer zur korrespondierenden Klammer |
| d% | lösche alles zwischen dieser Klammer und der korrespondierenden |
| c% | ersetze alles zwischen dieser Klammer und der korrespondierenden |
| y% | schiebe alles zwischen den Klammern in den Puffer |
| <% bzw. >% | Ein- bzw. Ausrücken des eingeklammerten Bereichs |
Mehrfachausführung
Soll ein Kommando mehrfach ausgeführt werden, stellt man einem beliebigen
Kommando die Häufigkeit voran. Beispiele:
| Kommando | Wirkung |
| 4dw | löscht die nächsten vier Worte |
| 77i - ESC | erzeugt 77 Bindestriche |
| 3cl | ersetzt die nächsten 3 Zeichen durch die Eingabe |
| 12yy | kopiert die nächsten 12 Zeilen in den Kopierpuffer |
Mach's nochmal, vi!
Ein Punkt wiederholt das letzte Kommando
Ein besonderes Feature von vi ist der Punkt. In der Kommandoebene eingegeben
wiederholt er das letzte Kommando an der aktuellen Cursorposition.
Auch vor dem Punkt kann man die Häufigkeit angeben. Hat man nach 10dd noch
10. getippt, werden 100 Zeilen gelöscht.
Schiefgelaufen
Wenn mal etwas schiefging:
Versehentliches Löschen und andere ungewollte Vorgänge kann man mit u (undo)
ungeschehen machen.
Befindet man sich in einem unbekannten Modus, erreicht man mit ESC die
Kommandoebene, von der aus das u eingegeben werden muss.
Undo nicht unbedingt mehrstufig
Stellt man fest, dass nicht der letzte, sondern der vorletzte Befehl den
Schaden verursacht hat, der 100 Seiten Manuskript mit der Schredderfunktion
bearbeitete, kann man zwei Dinge tun. Das erste ist, dass man u ein weiteres
Mal drückt und hofft, eine der neueren Implementationen von vi zu benutzen,
die ein Undo in mehreren Stufen erlauben. Es kann aber auch sein, dass statt
der mehrstufigen Änderung nur ein Redo erfolgt ist. Dann sollte man aufstehen,
tief durchatmen und überlegen, in welchem Zustand sich die Datei auf der
Platte befindet und dann mit :q! verlassen, um die letzte Version zu
verwenden oder das Thema Zwischenspeichern noch einmal intensiv durchdenken.
Ein versierter vi-Benutzer würde an dieser Stelle allerdings den aktuellen
Text nicht mit :q! verwerfen, sondern ihn unter einem anderen Namen sichern.
Dazu wird :w gefolgt von einem Leerzeichen und dem neuen Dateinamen aufgerufen.
Also sichert :w sicher den Text unter dem Namen sicher.
Anschließend kann man mit dem Kommando diff
ermitteln, welche Unterschiede zwischen
sicher und dem letzten Stand bestehen.
Sollte statt dessen die verwendete Version ein mehrstufiges Undo beherrschen,
stellt sich die Frage, wie man ein Undo zuviel wieder rückgängig machen kann.
Hier empfielt sich ein Experiment mit ctrl-R.
Wichtige Befehle des Befehlsmodus
sichern und laden
Der Befehlsmodus wird mit dem Doppelpunkt aktiviert. Die Kommandos
q zum Verlassen und w zum Sichern wurden bereits vorgestellt. Auch
dass man dem Kommando w als Parameter noch einen Dateinamen mitgeben
kann, um den Text unter diesem Namen wegzuschreiben, wurde bereits erwähnt.
Als Gegenstück
zum w gibt es ein r (read), um Texte in den aktuellen Text hineinzulesen.
Auch hier wird der Dateiname als Parameter gegeben.
Der angegebene Text erscheint danach an der aktuellen Cursorposition.
Shellaufruf
Mit dem Ausrufezeichen wird die restliche Befehlszeile an eine Shell
weitergeleitet. Man kann so aus dem Editor einen Compiler starten oder
andere Systemkommandos geben. Probieren Sie einmal :!ls aus!
| Befehl | Wirkung |
| :n | Wurde vi mit mehreren Dateien aufgerufen, lade die nächste |
| :r Datei | Lade die Datei an der Cursorposition hinzu |
| :d | Lösche Zeile |
| :! Kommando | Es wird eine Shell gestartet, um das Kommando abzusetzen |
Befehle beginnen mit dem Zeilenbereich
Für viele Kommandos der Befehlszeile kann ein Bereich von Zeilen
vorangestellt werden, auf denen sie wirken sollen. So bewirkt
das Voranstellen einer 8 vor w datei, dass Zeile 8 unter dem Namen
datei gespeichert wird. Einen Bereich von Zeilen gibt man durch die
erste Zeilennummer, gefolgt von einem Komma und der Zahl der letzten Zeile
an. 12,15 bezeichnet also die Zeilen zwischen 12 und 15. Für bestimmte
Zeilen gibt es besondere Symbole. Die aktuelle Zeile, in der sich der
Cursor befindet, wird durch einen Punkt bezeichnet. Das Dollarzeichen
bezeichnet die letzte Zeile. Innerhalb der Bereichsangabe darf kein
Leerzeichen stehen.
| Angabe | Bereich |
| 25 | die Zeile 25 |
| 5,25 | der Bereich von Zeile 5 bis 25 |
| .,25 | der Bereich von der aktuellen Zeile bis Zeile 25 |
| 25,$ | von Zeile 25 bis Dateiende |
| .,$ | von aktueller Zeile bis Dateiende |
Ersetzen
Zum Ersetzen einer Zeichenfolge durch eine andere muss man zunächst durch
Doppelpunkt in den Befehlsmodus wechseln. Der folgende Befehl bewirkt das
Ersetzen der Zeichenkette >>suchmuster<< durch die Zeichenkette >>ersetze<<
im gesamten Text.2)
:1,$ s/suchmuster/ersetze/g
|
Dieser Befehl sollte zunächst am Leerzeichen in zwei Teile zerlegt
werden.
Der Bereich, in dem der Befehl wirkt, wird gleich zu Anfang der Zeile
angegeben. Steht dort nichts wird nur die aktuelle Zeile herangezogen.
In diesem Fall heißt 1,$ von der ersten bis zur letzten Zeile.
Das Dollarzeichen als Symbol für das Ende ist in vi durchgängig.
Dann folgt der Befehl s für suchen (engl. search). Das Suchmuster und die
Ersetzung müssen voneinander und von den Kommandos vorher und nachher
abgetrennt werden. Dazu wird meist der Schrägstrich verwendet. Es könnte auch
jedes andere Zeichen sein, das im Suchmuster nicht vorkommt. Am Ende
kommt das g (global), damit die Ersetzung nicht beim ersten Mal stehen bleibt.
Das Suchmuster ist übrigens ein regulärer Ausdruck, so wie er auch von
grep verwendet wird.
Settings
Um Optionen ein oder abzuschalten, geht man zunächst mit dem Doppelpunkt
in den Befehlsmodus und gibt dort set, gefolgt von der Option an.
Man kann vi durch viele Optionen konfigurieren. Die verschiedenen
Implementationen bieten da unterschiedliche Möglichkeiten. Um eine Übersicht
zu erhalten, gibt man set all an und blättert sich mit der Leertaste
durch die Seiten. Mit ESC kommt man zurück in den Kommandomodus.
| Einschalten | Ausschalten | Wirkung |
| set all | | zeigt die aktuellen Settings an |
| set list | set nolist | zeigt Sonderzeichen an |
| set sw n | | (shiftwidth) setze Einrücklevel auf n Stellen |
| set ai | set noai | (autoinsert) Automatisches Einrücken |
| set nu | set nonu | (number) Zeilennummern anzeigen |
| set smd | set nosmd | (showmode) zeige den Textmodus an |
| set sm | set nosm | (showmatch) Anzeige der Gegenklammer bei Eingabe |
Steuerung des Zeilenumbruchs
vi bricht die Anzeige am Ende jeder Zeile um. Dieses Verhalten kann
in manchen Fällen sehr lästig sein. Durch nowrap schaltet man
es ab, mit wrap wieder ein. Bei der Texteingabe wird erst
bei Return eine neue Zeile erzeugt. Dieses kann man durch
wm (wrapmargin) ändern. Gibt man eine Zahl ungleich 0 an, wird
so viele Zeichen vor Erreichen des rechten Rands umgebrochen. Dabei
bricht vi immer wortweise um. Er nimmt also das angefangene
Wort mit in die neue Zeile und fügt davor ein Zeilenumbruchzeichen (new line)
ein.
Literatur
Arnold Robbins, Imke Schenk (Übersetzer): vi- Editor. Kurz und gut. O'Reilly, 2000.
1 Man kann
darüber streiten, ob diese Taste als Abschluss der Eingabe eine
glückliche
Wahl war. Inzwischen verwenden fast alle Programme die ESC-Taste unter der
Bedeutung des Verwerfens von Eingaben. Unter vi jedenfalls wird die Eingabe
belassen und der Modus verlassen.
2 Dies ist
mein Lieblingsbefehl. Nennen Sie diese Folge von Buchstaben mit der Anmerkung
"...ist doch eigentlich naheliegend, oder?" und man wird Ihren Namen nur noch
in Ehrfurcht aussprechen.