Vi

Tastaturorientierter Texteditor
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 18. November 2005 um 03:50 Uhr durch 85.181.103.91 (Diskussion) (Kommando-Systematik verstehen). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Vi ("vi" für "visual"; ausgesprochen [ vi: ai ], aber nicht [ vi: ] und auch nicht "sechs" oder "six" wie die römische Zahl VI) ist ein 1976 von Bill Joy für eine frühe BSD-Version geschriebener und von POSIX standardisierter Texteditor. Der Name stammt von "Visual Interface", weil sein Vorgänger ex ein einfacher Zeileneditor war.

Vi wurde schnell zum De-Facto-Standardeditor unter Unix (auch für Hacker), jedenfalls bis zum Aufstieg von Emacs um etwa 1984. Aufgrund seiner Schlankheit startet er schneller und benötigt weniger Speicherplatz als Emacs. Sogar auf einer Rettungsdiskette hat Vi auch heute noch Platz, so dass entweder Vi selbst oder einer seiner Klone (Vim, Nvi, elvis, ...) Bestandteil fast aller Unix-/Linux-Distributionen ist.

1991 benutzten ungefähr die Hälfte aller Teilnehmer einer Usenet-Umfrage den Vi. Auch heutzutage ist Vi zumindest in der Unixwelt noch sehr verbreitet, selbst Emacs-Benutzer greifen ab und zu auf ihn zurück, wenn es mal schnell gehen soll. Außerdem kann man mit diesem Editor in Kombination mit rsh oder ssh (früher mit Telnet) im Netzwerk sehr gut auf anderen Rechnern arbeiten.

Datei:Vim.jpg

Vi-Arbeitsmodi

Neueinsteiger brauchen für Vi eine hohe Frustrationstoleranz, da es sich um einen Editor mit drei grundsätzlich unterschiedlichen Arbeitsmodi handelt. Dabei ist es ganz einfach, wenn man erst einmal die Arbeitsweise der einzelnen Modi verstanden hat und weiss, wie man von einem in den anderen Modus wechselt (siehe Grafik unten). Die drei Modi sind:

  • Befehlsmodus (command mode)
Beim Start von Vi befindet man sich im Befehlsmodus. Dort können durch verschiedene Tastendrücke einfache Befehle ausgeführt, wie z.B. "Wort suchen", "Zeile löschen" usw. Durch drücken von [i] gelangt man in den Einfüge-Modus.
  • Einfügemodus (insert mode)
Im Einfügemodus ist die eigentliche Eingabe von Text möglich. Durch drücken von ESC gelangt man wieder in den Befehls-Modus zurück.
  • Kommandozeilenmodus (auch Komplexbefehlsmodus, colon mode oder ex mode)
Durch Eingabe von ':' gelangt man vom Befehlsmodus in den Kommandozeilenmodus. Dort können komplexere Befehle ausgeführt werden, wie etwa Suchen und ersetzen von Text (:s/alter_text/neuer_text/g).

Frühere Versionen gaben dem Benutzer kein Indiz, in welchem Modus er sich gerade befand, so dass es auch heute noch typisch für den Vi-Benutzer ist, immer vorsichtshalber noch einmal [ESC] zu drücken, um ganz sicher zu gehen, dass er sich wirklich im Befehlsmodus befindet (falls das vorher schon der Fall war, wird Vi einfach nur piepsen). Aktuelle Versionen von Vi deuten ihren augenblicklichen Modus auf der Statuszeile oder grafisch an (siehe Screenshot unterste Zeile - der Modus ist "EINFÜGEN").

                                   +-------------------+
                                   | |  Start mit:     |
                                   | v  vi dateiname   |
+-------------------+--------------+-------------------+--------------+-------------------+
|                   |              |                   |              |                   |
| Kommandozeilen-   |  <---------  | Befehls-Modus     |  --------->  | Einfüge-Modus     |
| Modus             |     ":"      |                   |  [i], [a],   |                   |
|                   |              | Verwendung von:   |  [o] usw.    |                   |
|                   |              | yy, p, dd, J      |              | Normales Editie-  |
| z.B. "wq", "q!"   |              | usw.              |              | ren, Pfeiltasten  |
| oder komplexe     |              |                   |              | Bildscrollen usw. |
| Befehle, wie      |  [ENTER]     | (Der Vi startet   |    [ESC]     |                   |
| Suchen & Ersetzen |  --------->  | in diesem Modus)  |  <---------  |                   |
|                   |              |                   |              |                   |
+-------------------+--------------+-------------------+--------------+-------------------+
                                   | |  Beenden mit    |
                                   | v  ":wq" od. "ZZ" |
                                   +-------------------+

(wenige Ausnahmen, wie z.B. das Zurückspringen des [r]-Befehls in den Befehlsmodus ohne drücken von [ESC], existieren)

Vorteile

Ein großer Vorteil von Vi ist, dass mehrere Befehle nacheinander ohne gleichzeitiges Betätigen der Alt-, Strg- oder sonstiger Modifier-Tasten abgesetzt werden können. Für den geübten Benutzer bedeutet das eine erhebliche Steigerung der Arbeitsgeschwindigkeit. So löscht zum Beispiel 3dw gleich drei Wörter auf einmal.

Vi Power-User

Während der Vi vielen Anfängern als "Zumutung" empfunden wird, findet man auch zahlreiche Power-User, die damit scheinbar "zaubern" können.

Alternative Sicht der Modi

Eine weniger verbreitete, alternative Sichtweise ist die, dass Vi keinen besonderen "Einfüge-Modus" hat, sondern

  • dass es eine Reihe von Befehlen gibt wie i, a, cw ...,
  • denen unmittelbar eine Texteingabe folgen muss,
  • welche wiederum mit [ESC] abzuschließen ist.

Dass diese Sicht der Dinge - auch wenn sie ungewöhnlich ist - etwas für sich hat, zeigt sich spätestens dann, wenn man einem Vi "Power-User" über die Schulter sieht: Dieser wird nicht nur i und R sondern

  • mindestens ein halbes Dutzend unterschiedlicher Befehle benutzen, um eine Textänderung einzuleiten, und
  • in der Regel sofort im Anschluss an jede Texteingabe wieder [ESC] drücken.

Somit besteht nie ein Zweifel, ob Vi sich denn nun im "Eingabe-Modus" oder im "Befehls-Modus" befindet: sieht man [ESC] als verpflichtenden abschließenden Bestandteil einer Texteingabe bzw. Änderung, gilt immer der Befehls-Modus und niemals wird versehentlich eine als Befehl gedachte Tastenfolge im editierten Text landen.

Textänderungen richtig einleiten

Obiges ist in der Praxis aber nur der kleinere Vorteil, sehr viel effizienzfördernder ist die Wahl des für den jeweiligen Zweck "richtigen" Befehls zur Einleitung einer Textänderung. Die folgenden Tabelle ist zwar unvollständig, zeigt aber eine praxisrelevante Auswahl:

i / a einfügen vor / hinter Cursor
I / A am Zeilenanfang / Zeilenende ein-/anfügen
o / O neue Zeile unter / über Cursor
S / C gesamte Zeile / Zeile ab Cursor bis Ende ersetzen
cw / ctx ab Cursor bis Wortende / bis zum Zeichen x ersetzen

(Im letzten Fall ist das Zeichen x frei wählbar, muss aber in der selben Zeile auftreten.)

Die höhere Arbeitsgeschwindigkeit resultiert vor allem daraus, dass man

  • vor der Änderung oft die Cursor-Positionierung spart und
  • nach der Änderung keine überschüssige Zeichen löschen muss, bzw.
  • während der Änderung kein Umschalten zwischen "Überschreiben" auf "Einfügen" nötig ist.

Mit Absicht wurde in der obigen Tabelle übrigens auf den R-Befehl verzichtet, den Vi-Neulinge wahrscheinlich als "Überschreibe-Modus" kennen und nutzen: Es kommt in der Praxis gar nicht so oft vor, dass "1:1" Zeichen zu ersetzen sind. Viel häufiger ist es dagegen erforderlich, ein gesamtes Wort oder z.B. alle Worte bis zum nächsten Komma zu überschreiben. Dann aber sind cw und ct, sehr viel praktischer, da man diese Befehle unabhängig davon verwenden kann, ob der neue Text länger oder kürzer ist: Es passiert stets genau das Richtige, d.h. es werden automatisch zusätzliche Zeichen eingefügt oder überschüssige gelöscht ... (und wenn der Ersatztext exakt die selbe Länge hat, funktioniert es natürlich auch :-).

Sehr nützlich: Letzte Änderung wiederholen

Ein auf den ersten Blick unscheinbarer, für den Power-User aber unverzichtbarer Befehl ist das Punkt-Kommando (.), welches die letzte Veränderung am Text wiederholt - typischerweise natürlich an anderer Stelle. Das Anhängen einer schließenden Klammer und eines Semikolon an die aktuelle Zeile sowie die drei nachfolgenden Zeilen erfordert mit A);[ESC]j.j.j. nur ganze 10 Tastendrücke (und keinen einzigen Griff zur Maus) - man versuche diese Vorgabe mit scheinbar "komfortableren" Editoren zu schlagen! Dabei spielt es keine Rolle

  • wo der Cursor ursprünglich in der ersten zu ändernden Zeile stand, und
  • welche Länge die insgesamt vier betroffenen Zeilen haben.

(Der A-Befehl hängt stets am Ende der aktuellen Zeile an, egal wo der Cursor steht und wie lang die Zeile ist, j geht eine Zeile nach unten und . wiederholt die letzte Veränderung - also das Anhängen der Klammer und des Semikolons.)

Die Möglichkeit, die letzte Änderung mittels . zu wiederholen funktioniert auch für Befehle mit löschender Wirkung: Mehrere aufeinanderfolgende Worte oder Zeilen werden am schnellsten mit dw... bzw. dd... entfernt.

Kommando-Systematik verstehen

Der in der obigen Tabelle zuletzt gezeigte Befehl (c) ist insofern besonders interessant, als er mit vielen anderen Vi-Befehlen kombiniert werden kann. Dazu wieder einige ausgewählte Beispiele, die nur das Prinzip verdeutlichen sollen:

t, Cursor vor das nächste Komma in der laufenden Zeile setzen
ct, Änderung einleiten, die sich bis vor das Komma erstreckt
2f( Cursor auf übernächste, öffnende Klammer setzen
c2f( Änderung einleiten vom Cursor bis inklusive übernächster Klammer

Im Fall von Veränderungen (c) ist die Eingabe wie Eingangs dargestellt durch [ESC] abzuschließen.

Kurzum, die vielfältigen Vi-Befehle zur Cursor-Positionierung lassen sich somit alle nach c einsetzen, um den zu ändernden Bereich anzugeben!

Aber das ist noch nicht alles, denn auch andere Kommandos lassen sich mit Befehlen zur Cursor-Poitionierung kombinieren. Hier nur einige wenige Beispiele:

dt, löscht vom Cursor bis zum nächsten Komma (ohne das Komma)
yt, kopiert vom Cursor bis zum nächsten Komma in einen Zwischenspeicher
d2f( löscht vom Cursor bis zur übernächsten Klammer (inklusive Klammer)
y2f( wie zuvor aber kein Löschen sondern Kopieren

(Der von y gefüllte Zwischenspeicher lässt mit den Befehlen p oder P an anderer Stelle wieder eingefügen.)

Da w für sich alleine den Cursor auf das nächste Wort setzt, sind wortweise wirkenden Befehle wie cw, dw und yw also nur Sonderfälle einer allgemeineren Systematik, und wer diese einmal verstanden hat, wird sich nicht mehr wundern, warum nach dG alle Zeilen bis zum Dateiende verschwinden.

Prinzip der Modularität

Eine andere Stärke des Vi liegt darin, dass er - anders als manche vergleichbaren Werkzeuge - im Laufe der Zeit zur nicht zur "eierlegenden Wollmilchsau" ausgebaut wurde, sondern stets die Zusammenarbeit mit vorhandenen Werkzeugen das Ziel war. So sind Unix/Linux u.a. für zahlreiche Programm bekannt, die textbasierte Aufgaben erledigen, sehr spezielle wie sort (Sortieren von Dateien), nl (Nummerieren von Zeilen) oder cb</cb> (Neuformatieren von C-Quelltexten), aber auch recht allgemeine wie sed oder awk.

Anstatt ähnliches im Vi erneut zu implementieren, erlaubt dieser Editor mit dem !-Befehl die Anwendung beliebiger externer Programme auf den editierten Text. Auch hier zur Verdeutlichung nur wenige Beispiele:

1,$!cb gesamte Datei (als C-Quelltext) neu formatieren
12,20!sort Zeilen 12 bis 20 aufsteigend sortieren
?BEGIN?,/END/!nl -ba Bereich zwischen den Zeilen, welche die Worte BEGIN und END enthalten, duchumerieren

Gegenüber vergleichbaren, "eingebauten" Features ergibt sich daraus zum einen der Vorteil, dass man z.B. zum Neuformatieren beliebige andere Werkzeuge (indent, astyle, ...) einsetzen kann.

Letzen Endes lässt sich alles, was sich auf irgend eine Art und Weise mit einem externen Programm machbar ist, auch mit Vi erledigen, etwa das:

%!nl -ba bad.cc | sort -k1rn | cut -c8-

Erst werden die Zeilen nummeriert, dann nach Nummern absteigend sortieren und schließlich werden die Zeilennummern wieder entfernt - effektiv wird also die Reihenfolge der Zeilen umgedreht ... ein Paradebeispiel dafür, dass ein Werkzeug, welches sich ganz universell mit vielen anderen kombinieren lässt, auch von "leistungsfähigerer" Konkurenz kaum zu übertreffen ist.

Keine Panik

Sicher ist schon mehr als ein Vi-Neuling in Panik verfallen, weil dieser "editor from hell" plötzlich Dinge als Kommando interpretierte, die eigentlich als Texteingabe gedacht waren. Hier hatte der Original Vi zugegebenermaßen eine Schwäche, da man mit u nur die allerletzte Änderung zurücknehmen konnte. Heute werden die meisten Vi-Benutzer wahrscheinlich unter Linux arbeiten und - mitunter unwissentlich - überhaupt nicht das Original sondern den modernen "Clone" Vim verwenden. Dieser erlaubt es per Default bis zu 1000 Änderungen rückgängig zu machen ... oder auch mit STRG-R erneut anzuwenden. Also kein Grund in Panik zu verfallen, wenn mal etwas nicht funktioniert, sondern einfach (oder mehrfach) den Befehl u benutzen.

(Das 1000-fache Undo ist eine der wenigen Default-Einstellungen, in denen Vim vom Original abweicht. Im Allgemeinen werden aber selbst erfahrene Vi-Benutzer den Unterschied zum Vim fast nicht bemerken - und wer beim Editieren niemals zwei Fehler hintereinander macht, kann auch im Vim die Anzahl der Undo-Levels auf den Wert 1 reduzieren ... :-))

Mnemonik und Eselsbrücken

Durch die (auch vom Vim erfüllte) Zielvorgabe, dass der Editor ohne Maus und Sondertasten benutzbar sein soll, andererseits die Editierbefehle aber kurz bleiben müssen (praktisch alles Wichtige ist mit ein bis zwei Tastendrücke zu erledigen, nur für seltenere Dinge wie etwa "Verwerfen aller erfolgten Änderungen" braucht man auch schon mal vier) ergibt sich zwangsläufig eine mangelhafte Mnemonik. Dennoch existieren häufig Eselsbrücken und so manches ist konsistenter, als es auf den ersten Blick scheint.

So wirken z.B. einige ähnliche Kommandos wie o und O oder p und P als Kleinbuchstabe unterhalb der aktuellen Zeile und als Großbuchstabe oberhalb (Merkhilfe: für Großbuchstaben braucht man die SHIFT-Taste, die i.d.R. mit einem breiten Pfeil nach oben gekennzeichet ist.) Die erwähnte Systematik gilt auch für das Suchen von Textstellen mit / (nach unten) und ? (nach oben), aber leider nur auf US-Tastaturen - nur dort liegt / auf derselben Taste, die mit SHIFT ein ? erzeugt.

Bewertung

Generell ist unbestreitbar, dass zum Umgang mit Vi im Vergleich zu "üblichen" Editoren eine hohe Eingewöhnungszeit erforderlich ist, die "Gelegenheitsbenutzer" typischerweise nicht investieren werden. Mitunter fehlt es auch nicht an der Zeit sondern an der Bereitschaft oder einer guten Einführung, die über die Anfangsschwierigkeiten hinweghilft, und vor allem die Motivation zum Weiterlernen aufrecht erhält, bis sich erste Erfolgserlebnisse einstellen. (Es wäre dsher schön, wenn dieser Wiki-Artikel nicht nur "Berührungsängste" abbauen sondern durch seine Beispiele auch motivierend wirken würde.)

Spätestens aber, wenn man sich daran gewöhnt hat, Textmuster einfach durch Eingabe eines Schrägstrich zu suchen, die letzte Suche einfach mit n in der selben oder N im umgehrter Richtung zu wiederholen, oder auf ganz ähnliche Art Textteile bis zu diesem Muster zu ändern, zu löschen oder zu kopieren, dann erscheinen Menüs und Mausklicks zum selben Zweck umständlich und zeitraubend und ein Pop-Fenster zur Eingabe des Suchmusters, das während der Anzeige der Fundstellen den Blick auf den Textzusammenhang versperrt, wird nur noch als störend empfunden.

Ist der Einstieg erst einmal gelungen, verfügt der Power-User mit dem Vi - und insbesondere mit dessen Open-Source-Clone Vim - über ein sehr mächtiges und an Effizienz kaum zu überbietendes Werkzeug, das viele Konkurrenten in den Schatten stellt, selbst wenn diese aufgrund von Menü- und Mausbedienung auf den ersten Blick "besser" erscheinen mögen. Kommen dann noch gute Kenntnisse anderer Unix-Tools hinzu, rückt der Horizont des mit dem Vi Möglichen fast ins Unendliche.

Zitate

Literatur

  • Vim - "Vi IMproved", ein deutlich leistungsfähigerer und benutzerfreundlicherer Vi-Klon
  • BVI - ein Editor für binäre Dateien, der mit den üblichen Vi-Kommandos zu bedienen ist
  • Kurzanleitung vi Zusammenfassung der wichtigsten vi-Kommandos auf einer A4-Seite
  • Vi-Cheat-Sheet The Semi-Official IBM developerWorks Vi-Cheat-Sheet (englisch)
  • The Traditional Vi Source Code des original vi's, mit Anpassungen um auf modernen Unix-Systemen zu kompilieren
  • WinVi Vi-Clone mit zusätzlichen Funktionen