E d i t i e r e n    m i t    vi[m]

  1. Einführung

    1. Anlass

      Anfang 2014 habe ich mich dazu entschieden, web-Seiten zu schreiben, die meine langjährigen Interessen und Ergebnisse in einen sinnvollen Rahmen zusammenfassen - Abschluss und Neuanfang zugleich. Um diese weitreichende Aufgabe zu verwirklichen, benötige ich einen Texteditor. Ich habe bisher eine Vielzahl von Texteditoren verwendet - um Programme bzw. Skripts zu schreiben. Um diese HTML-Seiten zu schreiben, habe ich mich für vi entschieden, obwohl ich bisher damit wenig Erfahrung hatte. Gründe sind:

      1. vi ist ein ausgereifter Editor, der alle nötigen Funktionen für diese Aufgabe - inkl. Syntax-Hervorhebung - unterstützt.
      2. vi ist ubiquitär. Er ist auf meinem Betriebssystem OSX - wie auf allen unixoiden Betriebssystemen - vorinstalliert. Zudem sind komfortable GUI-Versionen davon verfügbar - bei Bedarf auch auf Windows Betriebssystemen.
      3. vi ist Open Source und ohne Lizenzgebühr einsetzbar.
      4. Ich wollte etwas neues ausprobieren.

      Es gibt jedoch ein nicht zu unterschätzendes Hindernis: Es fehlen manche Automatismen u.a. die bewusste Umschaltung zwischen "Betriebsmodi". Daher ist, im Vergleich zur Mehrzahl der auf dem Markt verfügbaren Editoren, die Lernkurve anfänglich flach. Grundlegende Editierkonzepte übernahm vi von einem Editor namens ed aus der unix Frühzeit. Eine Einführung zu ed habe ich im Vorfeld verfassen, mit ed editieren, auf den zurückgegriffen wird, wenn der ex Editor ( siehe auch Kommandozeilenmodus ) untersucht wird. Bücher und vor allem unzählige Internetseiten wurden zu dem vi-Editor veröffentlicht. Einige - mehr oder weniger willkürlich - ausgewählte Beispiele sind im Lexikon unter vi verlinkt. Ohne diese nie versiegende Quelle, gespeist von der weltweiten Freiwilligen-Gemeinschaft, wären mir viele Aspekte des vi-Editors verborgen geblieben.
      Ziel ist es nun, aus dem Fundus eine gnoseologische Matrix zu skizzieren, die mir - und dem Leser - Mittel liefert, Erkundungen auf eigene Faust fortzusetzen.

      Diese Seiten setzten im Umgang mit vi ein Bisschen Erfahrung - sei es einige Stunden des Herumprobierens - voraus.

    2. Konventionen

      1. Die Zeile, wo der Cursor - vor dem nächsten Eintippen - steht, wird i.d.R. die laufende Zeile genannt.
        Das Zeichen, worauf der Cursor steht, das laufende Zeichen.

      2. Ein optionales Datum der Eingabe wird der Lesbarkeit halber in eckigen Klammen gefasst: [Option]: Sie gehören nicht zur Syntax.

      3. Ein erforderliches Datum der Eingabe wird gelegentlich in geschweiften Klammen geschrieben: {Textbezug}: Auch sie gehören nicht zur Syntax, sondern dienen der Übersichtlichkeit.

      4. Die Zeichenkette ... hinter einem Syntax-Element heißt dass, es wiederholt werden kann ([...]) oder muss ({...}).

      5. Die Verschachtelung der Elemente ist möglich.

    3. Wichtiger Hinweis

      Die meisten Erläuterungen unten dürften auf die vi "Grundversion" zutreffen. Jedoch treten Abweichungen zwischen vi-Dialekten auf. Beispielsweise

      • Bei der Durchführung mancher vi-Befehle, wie undo.
      • Im Initialisierungsprozess: Was tut der Editor, welche Dateien in welcher Reihenfolge er liest...

      Im Zweifelsfall beziehe ich mich auf die vim Version (vi-iMproved) namens MacVim.

  2. Editier-Modi

    Aus dem Texteditor ed stammt das Prinzip der expliziten Umschaltung zwischen Einfüg- und Befehls- Modus:

    1. Im Einfügmodus schreibt der User neuen Text.
      Diesen ruft er über einen Befehl auf und verlässt ihn stets über die ESC-Taste (Escape) - am Besten zweimal gedrückt. Der Aktivierungsbefehl hängt von der Situation ab:

      1. Ist der neue Text Zusatz oder Ersatz?
      2. Wo im Dateipuffer soll der neue Abschnitt hingelegt werden (anhängen, hinzufügen, vorsetzen)?

    2. Im Befehlsmodus erteilt der User Anweisungen. Davon gibt es 2 Arten: den vi-Befehlsmodus, die Kommandozeile.

      Manche Aktionen werden von beiden Befehlsmodi unterstützt. Beispiele: Cursor bewegen, Textteile finden/ersetzen/bewegen/kopieren, Einfügmodus aktivieren. Wenn eine Aktion auf den gesamten Dateipuffer zielt, ist die Kommandozeile effektiver. Manche Handhabungen werden ausschließlich über die Kommandozeile unterstützt. Beispiele: vi einstellen.

    Hinweis zu den Betriebsmodi:
    Anfang- und Grund- Zustand von vi ist der Befehlsmodus. Will der User neuen Text hinzufügen, muss er seine Absicht vi explizit mitteilen, d.h. den Einfügmodus aktivieren. Im Gegensatz dazu harren die meisten Texteditors standardmäßig im Einfügmodus. In den Befehlsmodus schalten sie dann um, wenn der User über Tastenkombination Aktionen auslösen will: z.B. das Suchen oder Ersetzen von Textteilen.

    Hinweis zu den Befehlsmodi:
    Die Aufteilung zwischen den Befehlsmodi stammt aus der doppelten Natur von vi, als visuelle Betriebsart von ex.

    1. Beispiele von authentischen vi-Befehlen
      • yy heißt (yank line) kopiere Inhalt der laufenden Zeile in den Standard-Speicherpuffer
      • ZZ heißt speichere Inhalt des Dateipuffers und beende Editiersitzung
      • i heißt (insert) füge neuen Text vor dem laufenden Zeichen ein.
    2. Beispiele von Befehlen aus der Kommandozeile (durch den Doppelpunkt : aktiviert), deren Mehrzahl ex-Befehle sind (wie in folgenden Beispielen der Fall ist):
      • :wq heißt (write and quit) speichere Inhalt des Dateipuffers und beende Editiersitzung
      • :%s/ZeichenKette1/Zeichenkette2/g heißt (substitute) Ersetze überall im Dateipuffer ZeichenKette1 mit ZeichenKette2.

    Zu den vi Betriebsmodi siehe auch Wikipedia vi

    Es ist möglich zwischen vi (visuelle) und ex (zeilenorientierte Betriebsart) hin und her zuschalten:

    • vi zu ex: Befehl Q eintippen
    • ex zu vi: Auf der ex-Kommandozeile (mit dem Zeichen : beginnend), Befehl vi eintippen

  3. vi aufrufen und beenden

    1. Voraussetzungen:

      1. Der User besitzt Lese- und Schreib- Zugriff auf das Arbeitsverzeichnis.
        Die einfachste Alternative in solchem Fall ist, dass der User ein Verzeichnis für die Datei nennt, wo er Schreibrechte hat.

      2. Der User verfügt über genug Speicherplatz, um seine Änderungen zu sichern.
        Die einfachste Alternative in solchem Fall ist es, noch während der Editiersitzung (im ex-Modus) eine Shell zu öffnen, und Platz zu schaffen (andere Dateien zu löschen) - siehe ex-Modus.

    2. vi aufrufen

      Eingabe Beschreibung
      vi [Option] Dateiname

      vi öffnet die genannte Datei Dateiname. Sofern sie existiert und der Leser darauf Zugriffsrechte hat, wird der Dateiinhalt auf den vi Dateipuffer (im Arbeitsspeicher des Rechners) übertragen. Wird die Sitzung beendet, sichert vi den Pufferstand unter den anfangs genannten Dateinamen, es sei denn der User einen anderen Dateinamen für die Sicherung nennt.

      • Ist eine Datei mit demselben Namen vor Sicherung vorhanden, wird sie überschrieben.
      • Ansonsten wird sie erzeugt.

      Beim Eröffnen der Sitzung setzt der Editor den Cursor, je nach Variante, an eine gegebene Textstelle.

      • vi an das Ende des Textes.
      • MacVim an den Anfang des Textes.

      Über eine Option kann diese Position überbestimmt werden: Der User kann einen Bewegungsbefehl nennen, der vor seinem ersten Editierbefehl ausgeführt wird.

      • +n bewegt den Cursor auf Zeile Nummer n des Textes.
      • +/Zeichenmuster bewegt den Cursor auf das erste Auftreten von Zeichenmuster.
      • Anstatt des Zeichens + kann die Zeichenkette -c (POSIX-Version) verwendet werden, um das gleiche Ergebnis zu erreichen.

      Beispiele:

      • vi +5 meineDatei.txt öffnet Datei meineDatei.txt und setzt den Cursor am Anfang von Zeile Nummer 5 (siehe Pos_1).
      • vi +/HIER meineDatei.txt öffnet Datei meineDatei.txt und setzt den Cursor auf das erste Auftreten von Zeichenmuster HIER im Text.

      Anm.: Ist der Bewegungsbefehl nicht durchführbar - z.B. Zeilennummer außerhalb des Textbereiches -, ignoriert vi ihn.

      vi

      Ist beim Aufruf keinen Dateinamen eingegeben, ist der vi Dateipuffer nicht verbunden.
      Beim Beenden der Sitzung muss aber der User eine Datei nennen, um den Pufferstand zu sichern.

      vi - R Dateiname
      view Dateiname

      vi bearbeitet Datei Dateiname im nur-Lesen-Modus (read only). Da vi auf einem Dateipuffer arbeitet, hat diese Option erst eine Auswirkung, wenn die Sitzung beendet wird - siehe vi quit.

      • Es ist möglich, nachträglich in den Schreibmodus umzuschalten.
      • Ein Kuriosum: Es ist sogar möglich, vi im Lesemodus ohne Dateinamen (vi - R bzw. view) aufzurufen.
      Das Eigenmerkmal des Lesemodus scheint darin zu bestehen, nach Änderungen des Dateipuffers, die Editiersitzung mit einem einfachen quit-Befehl (q) - ohne Erzwing-Option (!) - beenden zu dürfen.

      Tabelle: vi aufrufen

    3. vi beenden

      Eingabe Auswirkung / Erläuterungen
      ZZ

      vi Befehlsmodus
      Der Stand vom Dateipuffer wird in die verlinkte Datei gesichert und die Sitzung wird beendet. Ist kein Dateiname bei Eröffnung der Sitzung eingetippt, wirft vi den Fehler Kein Dateiname.

      :wq[!] [Dateiname]

      ex-Modus
      Der Stand vom Dateipuffer wird in die verlinkte Datei gesichert (write) und die Sitzung wird beendet (quit).

      • Ist kein Dateiname eingegeben, ist die verlinkte Datei möglicherweise die Datei, deren Namen beim Eröffnen der Sitzung eingetippt wurde.
      • Ist ein Dateiname eingetippt, sichert vi den Pufferstand dahin - je nach Lage überschreibt eine vorhandene Datei oder erzeugt eine neue Datei.
      • Mit Angabe der Option ! erzwingt der User den Schreibvorgang.
        (Eventuelle Fragen/Einwände von vi werden übersprungen z.B. wird dadurch der Lese-Modus ggf. außer Kraft gesetzt).

      :q[!]

      ex-Modus
      Die Sitzung wird beendet (quit) und der Stand vom Dateipuffer nicht gesichert.

      • Mit Angabe der Option ! erzwingt der User den Exit-Vorgang.
        Wurde der Dateipuffer seit Beginn der Sitzung geändert, und fehlt Option !, fragt vi, ob die Sitzung wirklich (ohne Datensicherung) beendet werden soll.

      Tabelle: vi beenden

      Zwischen Anfang und Ende einer Sitzung muss der User mindestens einmal in den Einfügmodus umschalten, um den Text zu ändern.

  4. vi-Syntax

    1. Überblick
      Jeder vi-Befehl besteht aus 3 Elementen, die über Permutationen oder Omissionen kombiniert werden.

      1. [Multiplikator] Aktion [Text-Bezug]
      2. Aktion [Multiplikator] [Text-Bezug]
      3. [Aktion] [Multiplikator] Text-Bezug

      Ein Befehl entspricht dem (Imperativ- oder Infinitiv-) Satz einer natürlichen Sprache:

      1. 'Aktion' ist das Verb:
        Wird es weggelassen, gilt Aktion 'Cursor Bewegen'.

      2. 'Text-Bezug' ist das Komplement:
        Es bestimmt in welchem Umfang die Aktion gilt. Es wird immer als letztes eingegeben.

      3. 'Multiplikator' entspricht in etwa ein Adverb oder Adjektiv. Es kann vor oder nach dem Verb eingegeben werden.

      Hinweis: Die ex-Syntax enthält dieselben Bausteine. Unterschiede ergeben sich jedoch aufgrund der Zeilenorientierung von ex. Das Thema wird in Abschnitt Kommandozeilenmodus behandelt.

    2. Morphem vom Typ 'Aktion'
      setzt sich aus einem bis zwei Buchstaben zusammen. Beispiele: (insert) i, I, (append) a, A, (open line) o , O, (delete) d, D, dd, (change) c, C, cc, (go) G, (yank) y, yy, Y.

      Für denselben Grundbefehl (bzw. Buchstaben) gibt es oft mehrere Varianten, die sich aufgrund des Text-Bezugs bzw. des Wirkungsbereichs unterscheiden:

      Variante Bedeutung
      Kleingeschrieben

      Die Aktion erfordert i.d.R. einen expliziten Text-Bezug (Zielposition).
      Beispiele: c (change), d (delete), y (yank)

      Großgeschrieben

      Die Aktion bezieht sich i.d.R. auf die laufende Zeile.
      Beispiele: C (change rest of line), D (delete rest of line), Y (yank line)

      Kleingeschriebener Doppelbuchstabe

      Die Aktion bezieht sich i.d.R. auf die laufende Zeile (oft anders als die großgeschriebene Variante).
      Beispiele: cc (change line), dd (delete line), yy (yank line)

      Tabelle: Syntaktische Varianten derselben Grundaktion

    3. Morphem vom Typ 'Text-Bezug'
      vermittelt in Kombination mit einer Aktion ihren Wirkungsbereich: Da die Anfangsposition des Wirkungsbereiches fast immer die laufende Cursor-Position ist, entspricht der Text-Bezug der Zielposition des Cursors.

      • Ein Text-Bezug kann - wie ein Befehl - mithilfe eines Buchstabens definiert werden: z.B. w, W, e, E, b, B, f, F.
      • Ein Text-Bezug kann mit Hilfe eines nicht-alphanumerischen Zeichen definiert werden: z.B. |, (, ), {, }
      • Ein Text-Bezug kann mit Hilfe eines Suchmusters definiert werden: z.B. /Zeichenmuster, ?Zeichenmuster

    4. Morphem vom Typ 'Multiplikator'
      erweitert den Text-Bezug - anstatt des ersten Auftretens wird z.B. das n-te Auftreten des Text-Bezugs anvisiert.

      Anm.: Die vi-Einstellung set (no)wrapscan entscheidet darüber, ob das Suchen an der 'Textgrenze' - je nach Suchrichtung Anfang oder Ende - abbricht - siehe auch vi einstellen.

    5. Beispiele von vi-Befehlen
      Zur Veranschaulichung werden Varianten der Aktion Textabschnitt löschen erläutert. (Nachfolgende Kapitel behandeln die weiteren Befehle.)

      Variante Durchführung
      2dW

      Ziel: Die 2 nächsten Worte ab der Cursorposition löschen. Allgemein wird ein Wort als Zeichenkette zwischen Trennzeichen definiert.
      vi unterscheidet zwischen 2 Wortarten (w und W) - siehe auch hier.

      3dB

      Ziel: Die 3 letzten Worte vor der Cursorposition löschen. Der Unterschied zwischen B und b entspricht dem zwischen W und w.

      d/muster

      Ziel: Alles ab der Cursorposition bis zum Zeichen vor Auftreten des Zeichenmusters muster löschen.

      • Eine Zahl-Eingabe, derart n/muster, bewirkt, dass nach dem n-ten Auftreten des Zeichenmusters ab der Cursor-Position gesucht wird.
      • Kann das Zeichenmuster nicht so wie eingegeben gefunden werden, wird der Befehl ignoriert.
      • Wird anstatt der Option / Option ? herangezogen (derart n?muster), kehrt sich die Suchrichtung um (rückwärts statt vorwärts).

      D

      Ziel: Die restlichen Zeichen der laufenden Zeile ab der Cursor-Position inklusiv löschen.

      dd

      Ziel: Die gesamte laufende Zeile löschen (unabhängig davon, wo sich der Cursor befindet).

      Tabelle: Beispiele von Varianten der Aktion "löschen" (delete)

  5. vi-Text-Bezug

    1. Überblick

      Ein Text-Bezug weist auf eine eindeutige Stelle im Dateipuffer hin. Eine Stelle reicht nicht aus, um einen Wirkungsbereich - [Ausgangspunkt=Quellbezug, Endpunkt=Zielbezug] - zu bestimmen - siehe auch Abschnitt vi Syntax.

      • Der Quellbezug ist von vi stets vorgegeben: Die Cursorposition unmittelbar vor Durchführung des Befehls. Je nach Fall entspricht der Quellbezug dem laufenden Zeichen oder der laufenden Zeile.
      • Der Zielbezug wird stets vom User eingegeben.

      Anmerkungen:

      1. Ohne explizite Eingabe einer Aktion bewirkt das Eintippen eines Text-Bezugs das Bewegen des Cursors im Text.
        Anm.: Es gibt einen Bewegbefehl in vi, 'G' (goto), der allerdings nur zeilenübergreifende Sprünge ermöglicht.

      2. Kann der eingegebene Text-Bezug nicht erreicht werden, wird meistens der Befehl ignoriert.

      3. vi unterscheidet zwischen zwei Alternativen, um den Cursor am Anfang einer Zeile zu positionieren:

        1. Der "absolute" Anfang einer Zeile heißt Position 0, Pos_0.
        2. Die Position des ersten Zeichen der Zeile, das kein Leer- oder Tab- Zeichen ist, heißt Position 1, Pos_1.

      4. vi erkennt das Zeilenende, aufgrund der Betriebssystem-spezifischen Markierung:

        1. Auf unixoiden Betriebssystemen: das LF Zeichen (Line-Feed bzw. Zeilenvorschub, ASCII-Code=10).
        2. Auf Windows Betriebssystemen: die CR-LF Zeichenkette (Carriage Return bzw. Wagenrücklauf, ASCII-Code=13, gefolgt von Line-Feed bzw. Zeilenvorschub, ASCII-Code=10).

        Springen auf das Zeilenende heißt den Cursor inmittelbar vor diese Markierung setzen.

    2. Inner-zeiliger Text-Bezug

      Eingabe Bewegung / Wirkungsbereich
      0

      Sprung auf den Zeilenanfang (Pos_0).

      ^

      Sprung auf den Zeilenanfang (Pos_1).

      $

      Sprung auf das Zeilenende.

      n|

      Sprung auf die n-te Spalte der laufenden Zeile.

      • Übersteigt der Sprung die Zeilengrenze, wird der Cursor auf das Zeilenende gesetzt.

      [n]h

      Sprung auf das n-te Zeichen vor Cursorposition.

      • Implizit ist n auf 1 gesetzt.
      • Der Cursor überspringt nicht die Zeilengrenze. Ist n zu groß, bleibt der Cursor am Anfang der Zeile.

      [n]l

      Sprung auf das n-te Zeichen nach Cursorposition.

      • Implizit ist n auf 1 gesetzt.
      • Der Cursor überspringt nicht die Zeilengrenze. Ist n zu groß, bleibt der Cursor am Ende der Zeile.

      [n]fx

      Sprung auf das in vorwärts Richtung zum n-ten Mal auftretende Zeichen x innerhalb der laufenden Zeile.

      • x entspricht einem beliebigen Zeichen.
      • Standardmäßig wird die Zahl n auf 1 gesetzt.

      [n]Fx

      Sprung auf das in rückwärts Richtung zum n-ten Mal auftretende Zeichen x innerhalb der laufenden Zeile.

      • x entspricht einem beliebigen Zeichen.
      • Standardmäßig wird die Zahl n auf 1 gesetzt.

      Tabelle: Textbezüge innerhalb der (laufenden) Zeile

      Anm. zur Tabelle 'Textbezüge innerhalb der Zeile':

      • Der Quell-Bezug ist stets die aktuelle Cursorposition.
      • Der Ziel-Bezug wird zeichengenaue festgelegt.

    3. Zeilen-übergreifender Text-Bezug

      Eingabe Bewegung / Wirkungsbereich
      [n]$

      Der Cursor springt vorwärts auf das zum n-ten Mal auftretende Zeilenende bzw. überspringt (n-1) Zeilen.

      [n]/[\c]{Muster}

      Der Cursor springt vorwärts auf das zum n-ten Mal auftretende Zeichenmuster.

      • Als gültige Zeichenmuster gelten auch Regular Expressions, die von vi interpretiert werden können.
      • Die Option \c unterdrückt die Unterscheidung zwischen groß- und klein- Buchstabierung.
        (Anm.: Die Unterscheidung kann generell über vi Einstellung :set ignorecase unterdrückt werden.)

      [n]?[\c]{Muster}

      Wie n/{Muster}, mit dem Unterschied, dass die Suche rückwärts geschieht.

      Tabelle: 'Zeichenorientierte Textbezüge, über die Zeilengrenze hinaus wirkend'

      Anm. zur Tabelle 'Zeichenorientierte Textbezüge, über die Zeilengrenze hinaus wirkend':

      • Der Quell-Bezug ist stets die aktuelle Cursorposition.
      • Der Ziel-Bezug ist zeichengenau festgelegt.

      [n]+

      (Zur laufenden Position) relativer Sprung n Zeilen nach unten (auf Pos_1 der Zielzeile).

      • Implizit wird n auf 1 gesetzt, die nächste Zeile.
      • Ist die anvisierte Zeile "hinter dem Textende", bleibt der Cursor auf dem Textende stehen.

      [n]-

      (Zur laufenden Position) relativer Sprung n Zeilen nach oben (auf Pos_1 der Zielzeile).

      • Implizit wird n auf 1 gesetzt, die vorherige Zeile.
      • Ist die anvisierte Zeile "vor dem Textanfang", bleibt der Cursor auf dem Textanfangs stehen.
      Tabelle: '1- Zeilenorientierte Textbezüge'

      Anm. zur Tabelle '1- Zeilenorientierte Textbezüge':
      • Der Quell-Bezug hängt von der Aktion ab:

        • Für Aktion 'v' (visual text selection) oder das bloße 'Cursor-Bewegen' die aktuelle Cursorposition.
        • Für andere Aktionen wie 'c', 'd' wird die laufende Zeile komplett einbezogen.

      • Der Ziel-Bezug ist Pos_1 der Zielzeile.

      [n]j

      Sprung n Zeilen nach unten.

      • Implizit wird n auf 1 gesetzt, die nächste Zeile.
      • Ist die anvisierte Zeile "hinter dem Textende", bleibt der Cursor auf dem Textende stehen.
      [n]k

      Sprung n Zeilen nach oben.

      • Implizit wird n auf 1 gesetzt, die vorherige Zeile.
      • Ist die anvisierte Zeile "vor dem Textanfang", bleibt der Cursor auf dem Textanfangs stehen.
      Tabelle: '2- Zeilenorientierte Textbezüge'

      Anm. zur Tabelle '2- Zeilenorientierte Textbezüge':
      • Für Aktion 'v' (visual text selection) oder das bloße 'Cursor-Bewegen' wechselt der Cursor die Zeile, bleibt aber auf der gleichen Spalte liegen, sofern es möglich ist - ansonsten wechselt er zeilenweilig auf das Zeilenende.
      • Für andere Aktionen z.B. 'c', 'd' werden die vollständigen Zeilen einbezogen (die Zielzeile bis Pos_1 bzw. Zeilenende).
      • Außerhalb von 'v' (visual Selektion) oder dem bloßen 'Cursor-Bewegen' sind die Textbezüge [n]+ und [n]j (bzw. [n]- und [n]k) gleichwertig.

      [n]w
      [n]W

      Sprung auf das n-te Auftreten des Anfangs eines "Wortes" in vorwärts Richtung.

      • Implizit wird n auf 1 gesetzt: Sprung auf das nächste Wort.
      • Bei der groß buchstabierten Variante (W) wird ein Wort als beliebige Zeichensequenz, die durch Leerzeichen oder Textanfang-, Textende-, Zeilenende- Zeichen abgegrenzt wird.
      • Die klein buchstabierte Variante (w) erfasst den Text in feineren Häppchen. Sie ist aufwändiger zu definieren:
        • Als Trennzeichen gelten zusätzliche Zeichen, darunter folgende Zeichen , ; : . - ( ) [ ] { }
        • Eine zusammenhängende Sequenz von Trennzeichen, unmittelbar (ohne Leerzeichen) angeschlossen an eine alphanumerische Sequenz, gilt als ein separates Wort.
        • Eine zusammenhängende Sequenz von Trennzeichen zwischen 2 Leerzeichen wird als ein separates Wort aufgefasst.

      [n]b
      [n]B

      Sprung auf das n-te Auftreten des Anfangs eines "Wortes" in rückwärts Richtung.

      • Implizit wird n auf 1 gesetzt: Sprung auf das Anfang des laufenden oder vorherigen Wortes.
      • Zur Wortdefinition für b siehe w. Zur Wortdefinition für B siehe W.
      [n]e
      [n]E

      Sprung auf das n-te Auftreten des Endes eines "Wortes" in vorwärts Richtung.

      • Implizit wird n auf 1 gesetzt: Sprung auf das nächste Wort-Ende.
      • Zur Wortdefinition für e siehe w. Zur Wortdefinition für E siehe W.
      Tabelle: 'Blockorientierte Textbezüge'

      Anm. zur Tabelle 'Blockorientierte Textbezüge':
      • vi definiert Textblöcke, je nach zugrundeliegendem Begriff: Wort, Satz, Absatz, Abschnitt. Nur Wort-bezogenen Textblöcke werden nachfolgend behandelt. (Die anderen Textblöcke werden je aufgrund einer zu speziellen Interpretation des Basis-Begriffs definiert.)
      • Der Quell-Bezug ist die aktuelle Cursorposition.
      • Der Ziel-Bezug ist die Grenze (Anfang, Ende) eines 'Textblocks'.

      H

      Sprung auf die obere Zeile vom Anzeige-Bildschirm.

      nH

      Sprung auf die n-te Bildschirmzeile, von oben abgezählt - siehe auch H.

      M

      Sprung auf die Zeile in der Bildschirm-Mitte.

      L

      Sprung auf die untere Zeile vom Anzeige-Bildschirm.

      nL

      Sprung auf die n-te Bildschirmzeile, von unten abgezählt - siehe auch L.

      Tabelle: 'Bildschirm-orientierte Textbezüge' (Sprung innerhalb des angezeigten Zeilenbereiches)

      Anm. zur Tabelle 'Bildschirm-orientierte Textbezüge'
      • Der Quellbezug hängt vor der bevorstehenden Aktion ab:
        • Für Aktion 'v' (visual text selection) oder das bloße "Cursor-Bewegen' die aktuelle Cursorposition.
        • Für Aktionen wie 'c', 'd' wird die laufende Zeile vor Durchführung komplett mitgezählt.
      • Der Cursor wird auf Pos_1 der Zielzeile gesetzt.
  6. vi-Einfügmodus

    Grundzustand des vi-Editors ist der Befehlsmodus. In den Einfügmodus umzuschalten heißt einen vi-Befehl (bzw. Tastenkombination) einzutippen, der dafür sorgt, dass jedes weitere eingetippte Zeichen den Text ändert. Zwei Möglichkeiten stehen zur Verfügung:

    1. Dauerhafte Umschaltung in den Einfügmodus
      i

      insert
      fügt Text vor der Cursorposition ein.

      I

      insert line
      fügt Text vor Pos_1 der laufenden Zeile ein.

      a

      append
      fügt Text nach der Cursorposition ein.

      A

      append line
      fügt Text am Ende der laufenden Zeile ein.

      o

      open line
      fügt Text auf einer neuen Zeile nach der laufenden Zeile ein. (Die laufende Zeile bleibt davon unberührt).

      O

      open line
      fügt Text auf einer neuen Zeile vor der laufenden Zeile ein. (Die laufende Zeile bleibt davon unberührt).

      c{Textbezug}

      change
      fügt Text anstelle des im Text-Bezug spezifizierten (vorhandenen) Textes ein.

      C

      change line
      fügt Text anstelle der Zeichen auf der laufenden Zeile, die sich nach der Cursorposition befinden, ein.

      [n]cc

      change line
      fügt Text anstelle der n Zeilen ab der laufenden Zeile inklusiv ein. Standardmäßig (implizit) wird n auf 1 gesetzt, nur die laufende Zeile wird komplett ersetzt.

      [n]s

      substitute
      fügt Text anstelle von n-Zeichen ab der Cursorposition inklusiv ein.
      Standardmäßig (implizit) wird n auf 1 gesetzt, nur das Zeichen unter dem Cursor wird ersetzt.

      Die Substitution wirkt sich nur innerhalb der laufenden Zeile: Sie hat keine Auswirkung auf nachfolgende Zeilen, auch wenn die eingegebene Zahl der zu ersetzenden Zeichen größer ist, als die Menge der restlichen Zeichen auf der laufenden Zeile.

      [n]S

      substitute line
      fügt Text anstelle der n Zeilen ab der laufenden Zeile inklusiv ein.
      Standardmäßig (implizit) wird n auf 1 gesetzt, nur die laufende Zeile wird ersetzt.

      R

      replace Text
      überschreibt den vorhandenen Text ab der Cursorposition inklusiv.

      Tabelle: 'Dauerhaftes Umschalten in den Einfügmodus'

      Um den Einfügmodus wieder zu verlassen, muss die ESC-Taste einmal (in mancher Situation reicht es nicht aus) oder zweimal (sicher ist sicher) gedrückt werden.

    2. Temporäre Umschaltung in den Einfügmodus

      [n]rx

      replace
      ersetzt n Zeichen ab Cursorposition inklusiv mit demselben Zeichen 'x'.

      Tabelle: 'Temporäres Umschalten in den Einfügmodus'

      Nach Ausführung des Befehls schaltet vi automatisch auf den Befehlsmodus zurück.

  7. vi-Befehlsmodus

    Die unten eingeführte Typologie der vi-Befehle erscheint mir praktisch. Die ersten 5 Abschnitte befassen sich mit Grundfunktionen des Editierens. Die weiteren Abschnitte gehen über die Grundlagen hinaus. Eine vollständige Abbildung der Möglichkeiten sind sie nicht. Je nach Dringlichkeit (der Sache) und Verfügbarkeit (meiner Person) werden Lücken behoben.

    1. Text selektieren

      Im Kombination mit einem Befehl kann ein Textbereich (der Wirkungsbereich des Befehls) immer über Textbezüge selektiert werden. Der User hat zudem die Möglichkeit eine visuelle Selektion über den Befehl 'v' zu veranlassen. Damit kann er den zu selektierenden Bereich visuell markiert, bevor er einen Befehl eintippt.

      Eingabe Durchführung
      v{Textbezug}[...] Visual selection zeichenorientiert bis zur im letzten Textbezug erreichten Cursorposition.
      V{Textbezug}[...] Visual selection zeilenorientiert bis zur im letzten Textbezug erreichten Cursorposition.
      {CTRL-V}{Textbezug}[...] Visual selection zeichenorientiert und spaltenweise bis zur im letzten Textbezug erreichten Cursorposition.
      Tabelle: Befehl 'Text selektieren'

      Anm. zur Tabelle 'Text selektieren'

      • vi bleibt in Selektionsmodus, solange der Cursor weiterbewegt wird - ein weiterer Testbezug eingetippt wird -, bis ein Befehl z.B. 'y' (yank), 'c' (change), 'd' (delete) erkannt wird. Der selektierte Abschnitt wird je nachdem (nur) zwischengespeichert oder auch ersetzt bzw. gelöscht.
      • Auch die Wiederholung desselben Selektionsbefehls ('v' bzw. 'V') schaltet den Selektionsmodus aus - ohne Zustandsänderung.
        Wird aber stattdessen zwischen groß- und klein- buchstabierter Version des Befehls (V oder v) gewechselt, bleibt der Selektionsmodus aktiv - nur dementsprechend umgeschaltet.

      GUI-Versionen von vim ermöglichen - wie jeder beliebiger Texteditor - die zeichengenaue Selektion eines Textabschnitts wie folgt:

      • Der während der Bewegung der linken gedrückten Maustaste erfasste Textabschnitt wird selektiert.
      • Durch gleichzeitiges Drücken der linken Maustaste und der UMSCHALT-Taste auf einer (Ziel-)Position wird ein Textabschnitt - ab der vorherigen Cursorposition - selektiert.

      Diese GUI-spezifischen Alternativen sind dem 'v' Befehl (+ Cursorbewegung) gleichwertig.
    2. Text Suchen

      Das 'Suchen im Text' entspricht einem bloßen 'Cursor-Bewegen' - Angabe einer Zielposition vom Cursor. Daher kommen zur Qualifizierung der Suche im Prinzip alle Textbezüge in Frage.

      Suchen nach einem Zeichenmuster:

      Meistens bezieht sich das Suchen auf eine Zielposition, welche mithilfe eines Zeichenmusters bestimmt wird:


      Das Zeichenmuster kann verbatim oder als vi Regular Expression eingegeben werden. Auch können über vi Einstellungen generelle Randbedingungen der Suche festgelegt werden. Anbei Beispiele:
      • Standardmäßig unterscheidet vi zwischen groß- und klein- buchstabiert.

        • ex-Kommando :set ignorecase bzw. :set ic unterdrückt die Unterscheidung.
        • ex-Kommando :set noignorecase bzw. :set noic aktiviert die Unterscheidung neu.
      • Ob das Suchen eines Musters an der Textgrenze Halt macht, wird über folgendes ex-Kommando gesteuert :set (no)wrapscan.
        Standardmäßig operiert vi in endloser Schleife um den Text herum: Die Option wrapscan ist aktiviert.

      Suchen nach der Zeile mit einer gegebenen Nummer:

      Alle Zeilen im Dateipuffer sind numeriert von 1 (die erste Zeile) bis $ (die letzte Zeile). Zeile 0 entspricht für vi einer hypothetischen Zeile vor der ersten Zeile: Diese Konvention ermöglicht es, einen Teil des Dateipuffers an den Textanfang zu bewegen oder kopieren, siehe auch Kommandozeilenmodus.

      Das 'Goto' Befehl ermöglicht es dem User, auf eine bestimmte Zeilennummer zu springen.

      Eingabe Durchführung
      [n]G

      Mithilfe vom 'Goto' Befehl springt der Cursor auf Pos_1 von Zeile Nummer n (absolute Angabe) - siehe auch n+ bzw. n-. Ist die Zeilennummer nicht eingegeben, springt der Cursor auf die letzte Zeile im Dateipuffer.

      STRG-G

      Dieser Befehl bewirkt keine Bewegung, sondern zeigt lediglich, die Nummer der laufenden Zeile im Bezug auf den gesamten Textumfang.

      Tabelle: 'Goto' Befehl

      Anmerkungen zur Tabelle 'Goto' Befehl

      • Im Bezug auf G:
        Im Kommandozeilenmodus ist es auch möglich, mithilfe des Befehls :n einen "absoluten" Zeilensprung zu veranlassen. Überhaupt sind viele zeilenorientierte Aktionen über den ex-Editor einfacher auszuführen, als im vi-Befehlsmodus.
      • Im Bezug auf STRG-G:
        Im Kommandozeilenmodus werden über die Befehl :set nu (:set number) bzw. :set nonu (:set nonumber) die Zeilennummer sichtbar oder unsichtbar.

    3. Textabschnitt löschen

      Eingabe Durchführung
      [n]d{Textbezug}
      d[n]{Textbezug}

      Delete zeichenweise
      Der von [n] {Textbezug} definierte Textbereich wird gelöscht.

      D

      Delete zeilenweise
      Die restlichen Zeichen der laufenden Zeile ab der Cursor-Position inklusiv werden gelöscht.
      (Textbezug wurde implizit bestimmt)

      dd

      Delete zeilenweise
      Die gesamte laufende Zeile wird gelöscht (unabhängig davon, wo sich der Cursor befindet)

      [n]x

      n Zeichen ab der Cursorposition inklusiv werden gelöscht.

      Tabelle: Befehl 'löschen' (delete)
    4. Textabschnitt zwischenspeichern

      1. Der Standard-Zwischenspeicher:

        Der User kann den expliziten 'yank' Befehl (y, Y, yy) eintippen, um einen Textabschnitt zwischenzuspeichern - um ihn später anderswohin einzufügen.

        Eingabe Durchführung
        [n]y{Textbezug}
        y[n]{Textbezug}

        Textabschnitt zeichenweise zwischenspeichern
        Der von [n] {Textbezug} definierte Textbereich wird zwischengespeichert.

        yy
        Y

        Textabschnitt zeilenweise zwischenspeichern
        Die laufende Zeile wird komplett zwischengespeichert
        (siehe auch in Hinblick auf die Bestimmung des Befehlswirkungsbereichs den Unterschied zu D und dd)

        Tabelle: Befehl 'Textabschnitt zwischenspeichern'

        Nicht nur der 'yank' Befehl bewirkt ein Kopieren des selektierten Textabschnittes in den (Standard-)Zwischenspeicher, sondern auch die Befehle 'change' (Textabschnitt-ersetzen) (c, C, cc) und delete (d, D, dd) (Textabschnitt-löschen).

        Der gespeicherte Textabschnitt wird über den 'paste' Befehl (p, P) wieder eingefügt.

        Eingabe Durchführung
        p
        Standard-Zwischenspeicher nach der laufenden Cursorposition einfügen.
        P

        Standard-Zwischenspeicher vor der laufenden Cursorposition einfügen.

        Tabelle: Befehl 'Textabschnitt einfügen' (paste)

      2. Gekennzeichnete Zwischenspeicher bzw. vi-Register:

        Außer dem Standard-Zwischenspeicher - in anderen Kontexten oft Clipboard genannt - ermöglicht vi die Handhabung von genannten Zwischenspeichern bzw. Registern. Davon gibt es zwei Kategorien:

        • Die Register 1 bis 9 (9 insgesamt)
        • Die Register a bis z (26 insgesamt)

        Mit Hilfe des doppelten Anführungszeichen " wird im p bzw. P Befehl auf den x-Puffer (x Ziffer oder Buchstabe) zurückgegriffen: Beispielsweise "ap, "2p.

        'Ziffer'-Register werden automatisch verwaltet. Register i (i=1,9) entspricht dem i-ten zuletzt gelöschten Textabschnitt. Register 1 beispielsweise speichert den zuletzt gelöschten Textabschnitt, Register 2 den zuvor gelöschten Abschnitt usw.

        Eingabe Durchführung
        "2p
        Fügt Register 2 (Textabschnitt, der im vorletzten Löschvorgang erfasst wurde) hinter der laufenden Cursorposition ein.
        "3P

        Fügt Register 3 (Textabschnitt, der im vor-vor-letzten Löschvorgang erfasst wurde) vor der laufenden Cursorposition ein.

        Tabelle: Anwendungsbeispiele von Ziffer-Registern

        Will man einen vor kurzem gelöschten Textabschnitt einfügen, ohne die exakte Register-Ziffer zu kennen, kann man folgenden Befehl wiederholen: "1p(u.)... (Die runden Klammer sind nicht Teil der Befehls-Syntax). Die Sequenz u. setzt sich aus den zwei Befehlen 'u' (Befehl 'undo' bzw. 'Rückgängig machen') und '.' (Befehl wiederholen). Sie wird solange eingetippt, bis der richtige Puffer gefunden wird - vorausgesetzt er befindet sich innerhalb der von vi zwischengespeicherten Reihe der gelöschten Abschnitte.

        Anm.: Die iterative Sequenz (u.)... funktioniert nur deswegen, weil der Wiederholungsbefehl '.' die Puffer-Nummer automatisch inkrementiert.

        Interessanter sind die 'Buchstaben'-Register, weil der User sie selbst verwaltet: Nach dem gleichen Schema wie z.B. im p-Befehl (paste) wird der 'a'-Puffer mithilfe von "a aktiviert. Die gleichen Befehle, wie für die Handhabung des Standard-Zwischenspeichers, können herangezogen werden: Der 'y'-Befehl (yank), der 'd'-Befehl (delete), der 'c'-Befehl (change).

        Entweder wird der 'Buchstaben'-Register neu initialisiert (Kleinbuchstabe) oder es wird ihm ein Textabschnitt angehängt (Großbuchstabe).

        Eingabe Durchführung
        "a2yy
        Speichert 2 Zeilen ab der laufenden Zeile inklusive in den a-genannten Speicher. Der frühere Inhalt des a-Puffers wird ersetzt.
        "Ay3f}

        Derselbe a-Puffer wird um den Textabschnitt, laufende Cursorposition bis zum dritten Auftreten des Zeichens '}' innerhalb derselben Zeile, erweitert.

        "by7w
        Speichert die nächsten 7 Worte (w) in den b-genannten Zwischenspeicher.
        "Cyy

        Hängt den Inhalt der laufenden Zeile dem c-genannten Zwischenspeicher an.

        Tabelle: Anwendungsbeispiele von Buchstaben-Registern

        Anmerkungen zu den Tabellen 'Register':

        • Die Definition von vi-Textabschnitten wird im Kap. Textbezug in vi-Befehlsmodus behandelt.
        • Ist ein Textabschnitt falsch definiert (bzw. nicht vorhanden), tut vi nichts: Der Register-Inhalt bleibt unverändert.
        • Mithilfe der Kommandozeile :reg(ister) wird der momentane Inhalt aller Register aufgezeigt. Der Standard-Zwischenspeicher wird übrigens mit den Zeichen * gekennzeichnet. In der vim-Standardeinstellung wird der Register-Inhalt in Datei ~/.viminfo gesichert und - während des Hochladens (startup) - gelesen. Über die Aufruf-Option (startup option) -i kann der Anwender ein anderes Verhalten erzwingen:

          • -i {DateiName}: Datei DateiName wird anstelle von ~/.viminfo herangezogen.
          • -i NONE: vi versucht nicht Register zu lesen und zu sichern.

        • Die Buchstaben-Register werden auch für das Sichern von Makros verwenden. Dasselbe Register wird daher entweder einen Textabschnitt oder eine Befehlssequenz speichert (nicht beides, es sei denn der Textabschnitt ist eine Befehlssequenz).

    5. Nützliche Befehle

      Eingabe Wirkung
      . (repeat) Wiederholt den letzten Befehl, der den Dateipuffer geändert hat (Es betrifft also nicht eine Cursorbewegung!).
      u (undo)
      Macht die letzte Änderung rückgängig. Wird der Befehl wiederholt, hängt die Wirkung von der vi-Variante ab.
      • Auf MacVim werden frühere Änderungen im Text der Reihe nach rückgängig gemacht.
      • In alten vi-Versionen hebt die Wiederholung die Aufhebung auf: Befehlssequenz uu tut also nichts.
      U (undo all)

      Setzt die Zeile auf den Initialzustand (als die Datei erst geöffnet wurde) zurück (Alle Änderungen der Editiersitzung werden aufgehoben).

      CTRL-J (join line) Fügt die laufende und ihre nachfolgende Zeile zusammen (das Zeilenende-Zeichen zwischen beiden Zeilen wird gelöscht).
      Tabelle Nützliche Befehle

    6. Textabschnitt markieren

      Es gibt eine weitere Möglichkeit, einen Text-Bezug zu erstellen: die bewusste Markierung einer beliebigen Position im Puffer. Auf eine markierte Position kann gesprungen.

      Eingabe Wirkung
      m{Buchstabe} Markiert die laufende Cursor-Position mit dem Buchstaben Buchstabe. Er wird zwischen Groß- und Klein- Buchstaben unterschieden: Marke x ist nicht gleich Marke X. Insgesamt stehen (2 x 26) 52 Marken zur Verfügung: a bis z, A bis Z.
      `{Buchstabe}

      Bewegt den Cursor genau auf die Position von Marke Buchstabe.

      '{Buchstabe} Bewegt den Cursor auf Pos_1 der Zeile, wo die Marke Buchstabe hingelegt wurde.
      ``

      Bewegt den Cursor genau auf die Position vor dem letzten Bewegungsbefehl.

      '' Bewegt den Cursor auf Pos_1 der Zeile, wo der Cursor vor dem letzten Bewegungsbefehl stand.
      Tabelle: 'Textabschnitt markieren'

    7. Bildschirm rollen:

      Befehle "Bildschirm rollen" wirken vordergründig auf die Anzeige und nur in zweiter Linie auf die Cursorposition im vi-Dateipuffer, wenn überhaupt. Dies erklärt auch, warum sie nicht in die Bereichsdefinition von Aktionen (siehe auch Textbezug) eingehen.

      Eingabe Wirkung
      [n]{CTRL-F}

      Den Anzeige-Bildschirm n-mal nach unten rollen.

      1. Standardmäßig (implizit) wird um einen Bildschirm gerollt.

      2. Vor der p-ten Iteration:
        Die erste Bildschirmzeile hat Nummer z1(p-1)
        Die letzte Bildschirmzeile hat Nummer z2(p-1)

        Nach der p-ten Iteration:
        z1(p) = z2(p-1) - 1 =
        z1(p) = z1(p-1) + ( z2(p-1) - z1(p-1) ) - 1 =
        z1(p) = z1(p-1) + ( k(p-1) - 1) - 1
        mit k(p-1) = Anzahl der Bildschirmzeilen vor der p-ten Iteration

        Ist k(p) = k (konstant), lässt sich z1(n) einfach ermitteln: z1(n) = z1(0) + n (k - 2)

        Anm.:
        Wenn die vi-Option set wrap aktiv ist, und manche Zeile die Bildschirmbreite übersteigt, werden je nach Iteration unterschiedlich viele Textzeilen übersprungen. In diesem Fall ist die letzte Formel nur eine Vereinfachung.

      3. Nach der Aktion befindet sich der Cursor am Anfang (Pos_1) der ersten Zeile vom Zielbildschirm, i.d.R. in Zeile Nummer z1(n):

        1. Überschneidet der Zielbildschirm einen Teil des Textes:
          Der Textbereich [z1(n), z1(n) + k(n) -1] bzw. [z1(n), Textende] wird dargestellt.

        2. Überschreitet Zeile Nummer z1(n) die Textgrenze:
          Der Cursor springt auf den Anfang der letzten Textzeile. Die restlichen Bildschirmzeilen weisen außerhalb des Dateipuffers hin.

      [n]{CTRL-B}

      Den Bildschirm n-mal nach oben rollen.
      Diese Operation ist die exakte Umkehrung von CTRL-F. Es gelten dieselben Prinzipien.

      • Standardmäßig (implizit) wird um einen Bildschirm gerollt.

      • Vor der p-ten Iteration:
        Die erste Bildschirmzeile hat Nummer z1(p-1)
        Die letzte Bildschirmzeile hat Nummer z2(p-1)

        Nach der p-ten Iteration:
        z1(p) = z1(p-1) - k(p-1) + 2
        mit k(p-1) = Anzahl der Bildschirmzeilen vor der p-ten Iteration

        Ist k(p) = k (konstant), lässt sich z1(n) einfach ermitteln: z1(n) = z1(0) - n (k - 2)

        Anm.:
        Wenn die vi-Option set wrap aktiv ist, und manche Zeile die Bildschirmbreite übersteigt, werden je nach Iteration unterschiedlich viele Textzeilen übersprungen. In diesem Fall ist die letzte Formel nur eine Vereinfachung.

      • Nach der Aktion befindet sich der Cursor am Anfang (Pos_1) der letzten Zeile vom Zielbildschirm: z2(n) = z1(n) + (k(n) - 1).

        1. Ist Zeile z1(n) erreichbar (bzw. z1(n) >= 1):
          Der Textbereich [z1(n), z1(n) + k(n) - 1] bzw. [z1(n), Textende] wird dargestellt.

        2. Ansonsten startet der Zielbildschirm bei der ersten Textzeile (z1=1) und zeigt der Bereich [1, k(n)-1] bzw. [1, Textende].

      Tabelle: 'Bildschirm ganzzahlig rollen'

      Anm. zur Tabelle 'Bildschirm ganzzahlig rollen'

      • Der erste (implizite) Bezug ist die erste Zeile des Quell-Bildschirms (wo sich der Cursor vor der Aktion befindet).
      • Zielposition ist entweder die erste (vorwärts Rollen) oder die letzte (rückwärts Rollen) Zeile des Ziel-Bildschirms (Jeweils ist ein ganzer Bildschirm in gewählter Rollrichtung verfügbar).
      • Die Bewegungsformel zu CTRL-F und CTRL-B wurden aufgrund von manuellen GUI-Tests der MacVim Variante abgeleitet. Es ist nicht ausgeschlossen, dass die Quelltext-Basis von verschiedenen vi(m)-Varianten anderen Spezifikationen folgt.

      [n]{CTRL-D} Den halben-Bildschirm n-mal nach unten rollen.
      [n]{CTRL-U}

      Den halben-Bildschirm n-mal nach oben rollen.

      Tabelle: 'Bildschirm halb rollen'

      Anm. zur Tabelle 'Bildschirm halb rollen':
      Der Unterschied zum ganzzahligen Rollen beträgt mehr als nur die Anzahl k der zu überspringenden Zeilen (welche erwartungsgemäß ca. halbiert wird).

      • Der erste (implizite) (Quell-)Bezug ist die laufende Zeile.
      • Zielposition ist die um einen halben Bildschirm danach (vorwärts Rollen) oder davor (rückwärts Rollen) gelegene Zeile - Der Cursor wird auf Pos_1 gesetzt.
      • Die Zielzeile hat im Bezug auf den Zielbildschirm möglichst dieselben Position, wie die Quellzeile im Bezug auf den Quellbildschirm.

      [n]{CTRL-E} Den Bildschirm n-mal um eine Zeile nach oben rollen. Solange die laufende Zeile auf dem Bildschirm angezeigt wird, bleibt die Cursorposition unverändert. Ansonsten wird die erste Bildschirmzeile zur laufenden Zeile.
      [n]{CTRL-Y}

      Den Bildschirm n-mal um eine Zeile nach unten rollen. Solange die laufende Zeile auf dem Bildschirm angezeigt wird, bleibt die Cursorposition unverändert. Ansonsten wird die letzte Bildschirmzeile zur laufenden Zeile.

      Tabelle: 'Bildschirm zeilig rollen' (Bildschirm um einzelne Zeilen rollen)

      Anm. zur Tabelle 'Bildschirm zeilig rollen':

      • Der Quell-Bezug ist entweder die erste (vorwärts Rollen) oder die letzte (rückwärts Rollen) Bildschirmzeile.
      • Die Cursorposition bleibt von der Aktion unberührt, solange die laufende Zeile im Anzeigebereich bleibt.

      zz oder z. Die laufende Zeile wird in die Bildschirm-Mitte positioniert (keine Änderung der Cursorposition im Bezug auf den Dateipuffer)
      z-

      Die laufende Zeile wird in auf die untere Bildschirmzeile positioniert (keine Änderung der Cursorposition im Bezug auf den Dateipuffer)

      {z}{CR} Die laufende Zeile wird in auf die obere Bildschirmzeile positioniert (keine Änderung der Cursorposition im Bezug auf den Dateipuffer)
      Tabelle: 'Laufende Zeile auf dem Bildschirm neu positionieren'

      Anm. zur Tabelle 'Laufende Zeile auf dem Bildschirm neu positionieren':

      • Die Cursorposition (im Bezug auf den Dateipuffer) bleibt von der Aktion unberührt.

    8. Makro erstellen

      Ein Makro entspricht einer geordneten Reihe von Befehlen, die der User definiert und einer Taste bzw. einer Tastenkombination zuordnet, um es später wiederholt aufzurufen. Makros sind also nichts Anderes als (kleine) Programme zur automatischen Bedienung einer Software - siehe auch Makro. Damit kann der Anwender viel Zeit (Tipperei) sparen. Daher bieten viele Office-Tools (Editors, Tabulators) den Anwendern ohne Hintergrundwissen in der Programmierung das Aufnehmen von Makros an. Auch der vi-Editor.

      Ein allgemeines Verständnis im Bereich der Programmierung und das Wissen darüber, wie vi Makros handhabt, ermöglicht einem dieses Werkzeug in höherem Maße zu nutzen - wie sich unten zeigen wird.

      q{x}{{Befehl}...}q

      Aufnahme des Makros

      • Tippt man den Kleinbuchstaben q im Befehlsmodus ein, beginnt das Aufnehmen des Makros.
      • Das nächste Zeichen entspricht dem Label (dem sogenannten vi-Register) für den späteren Makro-Aufruf: vi lässt nur einzelne Buchstaben zur Benennung eines Makros zu. Insgesamt 26 Makros können definiert werden. Bei der Definition des Makros gilt Folgendes:
        • Die Kleinbuchstabierung bewirkt eine Neuinitialisierung des Registers.
        • Die Großbuchstabierung bewirkt ggf. eine Erweiterung (ein Anhängen) des Registers.
        (Im Eingabe-Beispiel links wird das vi-Register x neu definiert.)
      • Jedes weitere Eintippen entspricht dem Befehl oder einer Befehlsreihe.
      • Die Aufnahme des Makros wird durch erneutes Eintippen des Kleinbuchstabens q beendet.
      @{x}

      Erstes Aufrufen des Makros mit dem Label x.

      [n]@@ Erneutes Aufrufen (Durchführung) des zuletzt aufgerufenen Makros. Die vorangestellte Zahl n (Multiplikator) gibt die Anzahl der Wiederholung an (Standard wird das Makro einmal durchgeführt).
      Tabelle: 'Makro erstellen'

      Anmerkung zur Tabelle 'Makro erstellen':

      • Um ein Makro zu löschen, wird das entsprechende Register leer überschrieben. Dies geschieht über die leere Neuaufnahme. Beispielsweise löscht die Eingabe qxq Makro x. Es gibt weitere Möglichkeiten Makro x zu löschen: über die ex-Kommandozeile.

        • :call setreg('x','')
        • :let @x = ''

        (Anm.: Für eine vertiefte Einsicht siehe den nächsten Abschnitt.)

      vi speichert ein gegebenes Makro im entsprechenden Buchstaben-Register: Makro a wird also im a-Register gesichert. (Anm.: Es sind dieselben Register, wie auch für die Zwischenspeicherung von Textabschnitten verwendet.)

      Der Anwender kann über (ex) Befehle auf der Kommandozeile jederzeit den Stand der Register überprüfen.

      :reg[[Buchstabe[,]]...]

      Anzeige des Inhalts von Registern:

      • Wird beispielsweise der Befehl :reg a, 2 eingetippt, werden die Register a und 2 aufgezeigt - siehe den Abschnitt Register zur Bedeutung der Ziffer-Register.

      • Wird nur :reg (ohne Liste) getippt, werden ALLE Register aufgezeigt. Interessant dabei ist die Tatsache, dass es mehr als nur die Buchstaben- und Ziffer- Register gibt. Anbei Beispiele:

        • Register * entspricht dem fliegenden Zwischenspeicher (Clippboard), der beispielsweise vom p -Befehl (paste) herangezogen wird, wurde kein Register (mit Hilfe von Morphem ") genannt.

        Der Inhalt aller Register - und vieles mehr - wird standardmäßig in Datei ~/.viminfo gesichert (eine versteckte Datei im Rootverzeichnis des Anwenders). Es lohnt sich einen Blick darauf zu werfen - ohne etwas zu überschreiben, es sei denn man weiß, was man tut.

      Tabelle 'Register'

  8. Kommandozeile

    1. Überblick

      Um die Kommandozeile einzuschalten, tippt der User das Zeichen : ein. vi öffnet daraufhin eine Leiste im unteren Bereich des Editierfensters, wo der User das gewünschte Kommando einträgt und mit der return-Taste quittiert.
      Die Kommandozeile ermöglicht Handhabungen, die im vi-Befehlsmodus nicht vorgesehen sind. Zudem ist er in der Formulierung oft flexibler und schneller, insbesondere wenn Änderungen den gesamten Dateipuffer betreffen.

      • Die meisten Befehle aus der Kommandozeile stammen aus dem ed-Editor.
      • Manche sind spezifische ex bzw. vi Befehle.
      • Eine weitere Möglichkeit besteht darin, den Befehlsinterpreter aufzurufen.

    2. Syntax und Grundbefehle

      Der Syntaxaufbau eines ex-Befehls beinhaltet die Grundelemente 'Textbezug' und 'Aktion', wie die vi-Syntax. Unterschiede entstehen aufgrund der Zeilenorientierung im Kommandozeile-Modus.

      Der ex-Editor ist eine Erweiterung (extension) vom ed-Editor aus der unix-Anfangszeit, unter Berücksichtigung der Rückwärtskompatibilität. Darum wird zu Syntax und grundlegenden Befehlen auf den ed-Editor verwiesen.

    3. Beispiele von vi-Befehlen auf der Kommandozeile

      Manche Befehle auf der Kommandozeile sind keine ed bzw. ex Befehle. Auf der nächsten Tabelle werden einige nützliche aufgelistet.

      :split
      :vsplit

      Teilt den zu bearbeitenden Text auf 2 unabhängige Bereiche nach einer waagrechten Linie auf (Der eine Editierbereich liegt über den anderen). Dies ermöglicht den User, auf zwei Stellen des gleichen Textes parallel zu arbeiten.

      Will der User eine Teilung nebeneinander anstatt übereinander erreichen, tippt er den Befehl :vsplit (vertical split).

      Der User kann den split-Befehl mehrfach wiederholen: Der Editierbereich, wo der Kursor sich gerade befindet, wenn der Befehl eingetippt wird, teilt sich daraufhin auf. Damit kann der User ein Mosaik von Editierbereichen erzeugen, wo er jeweils seine Bearbeitung desselben Textes fortsetzen kann, indem er darauf klickt.

      Um einen einzelnen Teilbereich zu schließen, tippt der User den quit-Befehl :q ein. Jeder Teilbereich muss einzeln geschlossen werden, bis das Editieren des Textes beendet wird.

      :tabnew {filename}

      Eröffnet einen neuen leeren Reiter - wenn ohne weitere Optionen eingetippt. Ansonsten wird die als Option genannte Datei in den neuen Reiter geöffnet.

      Referenzen (Deutsch)

      Referenzen (Englisch)

      Tabelle von spezifischen Kommandozeile-Befehlen

    4. Aufruf des Befehlsinterpreters

      Eigentlich ist die Möglichkeit Shell-Befehle einzugeben schon in ed implementiert - siehe Syntax und Grundbefehle. Wesentliche Merkmale dieser Handhabung werden im Folgenden zusammengefasst.

      Der Befehlsinterpreter - auch die Shell (shell) genannt - ermöglicht dem User eines unixoiden Betriebssystem auf der Console Inhalte zu verwalten und überhaupt arbeiten zu können. Die folgende Tabelle zeigt wie während einer vi-Sitzung solche Shell-Handhabung abgerufen wird.

      :!{UNIX_command}

      Der Befehl mit Namen UNIX_command wird durchgeführt. Die Liste der verfügbaren Befehle hängt vom ausgewählten Befehlsinterpreter ab, der über die shell Option vom set-Befehl identifiziert wird (Kommando :set shell? eintippen, um die Einstellung zu prüfen, oder :set shell=shell_Name, um die Einstellung zu ändern.). Für die Bash (Bourne Again Shell) stehen beispielsweise folgende Befehle auf OS X oder auf auf Linux zur Verfügung. Dem Sinne nach gilt das Schema auch für vi(m)-Implementierungen auf Microsoft Windows. Erwartungsgemäß fällt die Auswahl des Befehlsinterpreters - im Vergleich zu unix-Systemen - geringer aus - siehe CMD.EXE.

      :r!{UNIX_command}

      Wie im vorherigen Fall wird der Befehl UNIX_command vom aktiven Befehlsinterpreter ausgeführt. Im Unterschied dazu wird das Ergebnis (die Ausgabe des Kommandos) dem Text direkt hinter die Cursor-Position hinzugefügt. Beispielsweise wird der Bash Befehl :r !date Datum und Uhrzeit hinter die aktuelle Kursorposition hinzufügen. Leider behandelt MacVim z.B. den Befehl :r !date +%x nicht wie erwünscht (um das Datum im nationalen Format auszugeben): Egal wie das Kommando eingetragen wird, versteht er Option +%x nicht als Teil vom date-Befehl.

      Tabelle: Aufruf des Befehlsinterpreters
  9. vi einstellen

    1. Der set-Befehl

      Der vi-Editor ist konfigurierbar: Der User kann innerhalb eines bestimmten Rahmens Aussehen und Verhalten des Editors steuern. Eine erste Möglichkeit dazu ist der Kommandozeile-Befehl :set {Option}.

      :set
      :set all
      :set option?

      Es gibt verschiedene Typen von set-Optionen:

      • Schalter-Optionen, deren Wert sich als Ja/Nein bzw. aktiviert/deaktiviert interpretieren lässt. Die vi-Syntax dazu ist : set {Optionname} zur Aktivierung und : set no{Optionname} zur Deaktivierung. Beispiel: : set nu(umber) bzw. : set nonu(umber).
      • Optionen, deren Werte innerhalb einer begrenzten (im voraus bekannten) Menge liegt. Beim Eintippen des Befehls : set {Optionname}=Wert kann der User anstatt dessen, den Wert direkt einzutragen, den Tabulator eintippen und vi zeigt ihm einen zulässigen Wert nach dem anderen, bis der passende bestimmt wird.
      • Optionen, deren Werte aus einer unendlichen Menge (beliebig) bestimmt werden können.

      Meistens haben die Optionen einen langen Namen (der englischen Bezeichnung entsprechend) und einen kurzen Namen, der aus zwei Buchstaben besteht (i.d.R. die ersten 2 Buchstaben des langen Namens). Beispiele: nu/number, ru/ruler Der nackte set-Befehl (ohne Option) veranlasst vim eine Liste von Einstellungen (Option=Wert) aufzuzeigen. Wird Option :set all eingetippt, zeigt vi alle Einstellungen. Wenn der User nur über den Wert einer bestimmten Option fragen will, tippt er :set {Option-Name}? ein. Beispielsweise :set tabstop?, um zu wissen, wie vielen Leerzeichen der Tabulator entspricht.

      Tabelle: Handhabung des set-Befehls

      Im Folgenden werden wichtige Optionen vom set-Befehl (alphabetisch) aufgelistet.

      autoindent / noautoindent

      Die bestehende Einrückung des Textes wird nach einem Zeilenvorschub beibehalten. Dies ist insbesondere für Programmiersprache - inkl. HTML - unabdingbar.

      exrc / noexrc beeinflusst den Initialisierungsprozess - siehe unten.
      nu(mber) / nonu(mber)

      veranlasst vi die Zeilennummer ein- bzw. auszublenden.

      shell

      bestimmt welchen Befehlsinterpreter ggf. von vi aufgerufen wird Auf meinem Rechner gilt shell=/bin/bash.

      spell / nospell

      Aktiviert die Rechtsschreibprüfung. Standardmäßig setzt MacVim die englische Sprache voraus.

      spelllang

      Bestimmt die für die Rechtsschreibprüfung zu verwendete Sprache (bzw. das Wörterbuch).

      • set spelllang=de Deutsch
      • set spelllang=en Englisch
      • set spelllang=fr Französisch

      Für weitverbreitete Sprachen kann auch ein spezieller Dialekt eingestellt werden: de_DE, en_US, en_GB, fr_FR, fr_CA, usw. (Es ist unklar, ob vim zwischen Dialekten derselben Sprache unterscheidet).

      term

      bestimmt den Terminal-Typ, der wiederum über das Erscheinungsbild des Textes auf dem Bildmschirm inkl. der Syntax-Hervorhebung entscheidet. Für MacVim gilt standardmäßig term=gui_builtin.

      wrap / nowrap

      Diese option veranlasst vi, den Text entweder komplett innerhalb der Editierfläche zu zeigen oder - wenn die Option deaktiviert ist - zuzulassen, dass Teile von langen Zeilen, die aussehalb des Editierrahmens fallen, nicht angezeigt werden.

      wrapscan / nowrapscan

      Wenn die option aktiviert ist, wird vi Suchaktionen in endlose Schleife durchführen. Ansonsten wird das Suchen beendet, wenn das Textende erreicht wird.

      Tabelle: Beispiele von set-Optionen

    2. Dauerhafte Speicherung der Einstellungen

      Um zu vermeiden, dass der User immer wieder Einstellungen eintippt, werden solche Befehle in einer Datei gespeichert, die beim vi-Aufruf automatisch gelesen wird. Je nach Systemkonfiguration und verwendetem vi-Dialekt kommen verschiedene Dateien in Betracht. Meine Grundeinstellungen sind primär in (einer im Heimatverzeichnis versteckten) Datei namens ~/.vimrc gespeichert. Anbei ein Auszug dieser Datei auf meinem Rechner:

      BefehlErläuterung
      set nu All lines will be numbered
      set guifont=Monaco:h13 Selection of font name and size in gui
      set tabstop=4 Defines the tab length in spaces
      set shiftwidth=4 Defines indentation in spaces
      set expandtab tabs will be converted into spaces
      set lines=40 columns=150 dimension of new editing window
      set autoindent auto indentation
      set nowrap no text wrapping (show only part of the text, if a line is too lang to fit into the allocated window
      set nowrapscan no scan wrapping (search does not loop after reaching the end of text)
      colorscheme delek color scheme

      Weitere nützliche set-Optionen mit Erläuterung sind beispielsweise folgenden Tutorials zu entnehmen:

      Die .vimrc Datei dürfte von den meisten vim-Dialekten während der Initialisierungsphase berücksichtigt werden. Auch dürfte i.d.R. die Einstellung auf der eine-Datei-Basis ausreichen. Wer jedoch ein feineres Tuning benötigt, soll im nächsten Kapitel nachschlagen.

    3. Initialisierung von vim

      In Wirklichkeit aber gestaltet sich der Initialisierungsprozess komplexer - als nur eine feste Datei zu lesen. Anbei eine unvollständige Aufstellung der Initialisierungsschritte für den vim-Dialekt - nach Lamb, Robbins (1999).

      1. Option shell wird aus der Umgebungsvariable SHELL (/bin/bash). Option term wird aus der Umgebungsvariable TERM (xterm-256color).

      2. Wenn Aufrufsoption -u {Dateiname} wird die genannte Datei ausgeführt und der Rest der Initialisierung anschließend übersprungen.
        Die Option wird interpretiert: -u NONE heißt, dass alle weiteren Initialisierungsschritte übersprungen werden.

      3. Eine systemweite wimrc Datei wird gelesen, deren Speicherort im Quelltext festgeschrieben ist.
        Auf meinem Rechner /usr/share/wim/vimrc.

      4. Anweisungen werden zuerst ausgeführt, die aus folgenden Quellen der Reihe nach stammen:

        • Umgebungsvariable VIMINIT. Auf meinem Rechner VIMINIT ist leer.
        • ~/.vimrc oder - wenn die Datei nicht existiert - ~/_vimrc. Auf nicht-unix-Systemen werden die User-Dateien umgekehrt gesucht.
        • Umgebungsvariable EXINIT. Auf meinem Rechner EXINIT ist leer.
        • ~/.exrc oder (auf nicht-unix-Systemen) ~/_exrc

      5. Wurde die Option exrc gesetzt, sucht vim zusätzlich im Arbeitsverzeichnis nach der ersten Datei aus folgender Reihenfolge und führt die dort festgelegten Schritte aus (die restlichen Dateien werden ignoriert).

        • .vimrc
        • _vimrc
        • .exrc
        • _exrc

        Anm.: Auf nicht-unix-Systemen wird die Suchfolge zwischen .-Namen und _-Namen umgedreht.

      6. Wurde beim vim-Aufruf die Option -c eingetippt, werden alle der Option nachfolgenden Befehle ausgeführt.

      Über den Befehl :so {Dateiname} kann zudem der User jederzeit vim veranlassen, die in Datei Dateiname festgelegte Konfiguration zu übernehmen.

    4. Weitere Einstellungen

      Wie aus dem Inhalt der Beispieldatei .vimrc oben ersichtlich, stellen die set-Optionen nur eine Untermenge aller verfügbaren Einstellungen dar. Im folgenden Abschnitt werden manche der anderen Optionen erwähnt.

      colorscheme

      Beispielsweise :colorscheme delek (meine Einstellung). Das Schema entscheidet über das Aussehen des zu editierenden Textes inkl. Syntax-Hervorhebung. Der User kann mit dem highlight-Befehl eigene Schemata entwerfen. :hi(ghlight) Group_Name key_Name=Wert

      • Group_Name bestimmt das Terminal, wie z.B. term, cterm, gui, ctermfg, ctermbg,guifg, guibg
      • key_Name bestimmt eine der von vi definierten grammatischen Kategorien, wie z.B. Comment, Constant, Type, Identifier, PreProc, Statement, Special, Underlined, Error, Normal

      Erläuterungen dazu sind beispielsweise folgenden Seiten zu entnehmen

  10. vi Regular Expressions

    Regular Expressions (RE) dienen der Bestimmung von Text-Inhalten über Zeichenmuster, mit der Absicht sie zu finden (den Cursor dorthin zu bewegen), ersetzen oder löschen. Naturgemäß ist ein Teil davon in den Kapiteln vi-Textbezug und ed Befehle behandelt.

    Erläuterungen zu regular expressions in vim sind folgenden Links zu entnehmen:

    Englisch:

    1. A. Robbins: vim regexp
    2. Oleg Raisky: vim regexp
    3. Softpanorama: regexp

    Deutsch:

    1. Holger Trapp, TU-Chemnitz