Wenn es einen einzigen Vim-Befehl gibt, der das ganze Bedien-Modell zusammenfasst, dann ist es der Punkt: . wiederholt den letzten Edit-Befehl. Klingt unspektakulär — wird aber zum mächtigsten Werkzeug im täglichen Edit-Workflow, sobald man die zugrunde liegende Designphilosophie versteht. Vim-Edits werden bewusst so klein und atomar formuliert, dass sie wiederholbar bleiben. Wer in dieser Logik denkt, ersetzt ganze Macro-Sequenzen oder mehrfache :substitute-Aufrufe durch zwei Tasten: n., n., n.. Dieser Artikel klärt, was Vim genau als „letzten Edit" zählt, zeigt den klassischen Such-Edit-Repeat-Loop, listet die Grenzen des Punkt-Befehls und führt das Plugin vim-repeat als Brücke ein.

Was Vim als „letzten Edit" zählt

. wiederholt die zuletzt ausgeführte Edit-Operation. Was Vim als eine solche Operation zählt, ist präzise definiert: alles, was zwischen dem Eintritt in einen Edit-Modus und der Rückkehr in den Normal-Mode passiert ist.

Konkret zählt zu einem Edit-Block:

  • Ein Operator-Motion-Befehl wie dw, c$, >ap, gUiw.
  • Ein Operator mit doppeltem Buchstaben für die ganze Zeile: dd, yy, ==.
  • Eine Insert-Mode-Sequenz von i (oder a, o, c{motion}, s, ...) bis <Esc>.
  • Ein Einzel-Befehl wie x, X, ~, r<char>.
  • Eine Visual-Operation: Visual-Mode betreten, Bereich wählen, Operator drücken — wird als ein Block gespeichert.

Was nicht zählt:

  • Reine Motions wie j, w, gg, /pattern. Sie ändern den Buffer nicht und sind keine Edits.
  • Ex-Befehle wie :w, :s/foo/bar/g, :!cmd. Sie haben eigene Wiederholungs-Mechanismen — siehe unten.
  • Undo/Redo (u, <C-r>). Sie sind Meta-Operationen.

Diese Definition hat eine wichtige Konsequenz: . wiederholt nicht „die letzte Tastenfolge", sondern „die letzte buffer-verändernde Aktion". Wer zwischen zwei Edits navigiert oder eine Suche ausführt, ändert nichts an dem, was . wiederholen würde.

text Was zählt, was nicht
" 1. Edit: dw löscht ein Wort
dw

" 2. Motion: 5j springt fünf Zeilen runter
5j

" 3. .  → wiederholt dw, NICHT 5j (Motion zählt nicht)
.

" 4. Edit: ciwNEU<Esc> ändert das innere Wort
ciw NEU<Esc>

" 5. Suche: /foo<CR>
/foo<CR>

" 6. .  → wiederholt ciwNEU<Esc>, NICHT /foo
.

Der klassische Such-Edit-Repeat-Loop

Der häufigste praktische Einsatz von . ist die Kombination mit Suche. Das Muster:

1. Mit /pattern an die erste Stelle springen.
2. Edit ausführen — typischerweise eine kompakte Operator-Object-Sequenz.
3. Mit n zur nächsten Trefferstelle.
4. Mit . den Edit wiederholen.
5. Wiederholen ab Punkt 3.

In Tasten ausgedrückt: /foo<CR> einmal, dann cw bar<Esc> n . n . n . für jede weitere Stelle. Die einzige Tipparbeit ist der erste Edit — danach sind es zwei Tasten pro Vorkommen.

text Such-Edit-Repeat-Loop in Aktion
" Aufgabe: in einer Datei alle Vorkommen von "TODO" durch "DONE" ersetzen,
" aber jedes Vorkommen einzeln kontrolliert.

/TODO<CR>             " erste Stelle finden
cw DONE<Esc>          " Wort ändern (change inner word — Stelle ändern)
n                     " nächste Stelle finden
.                     " denselben Edit wiederholen
n                     " nächste
.                     " wiederholen
" ... so weiter, bis Vim "search hit BOTTOM, continuing at TOP" sagt

Vergleich zu Alternativen:

  • :%s/TODO/DONE/gc würde alle ersetzen mit interaktiver Bestätigung. Etwa gleich schnell, aber als Ex-Befehl in einer Pipeline weniger flexibel.
  • :%s/TODO/DONE/g ersetzt alle auf einmal. Schnellste Variante, aber keine Kontrolle über einzelne Stellen.
  • Klassisches IDE-Find-and-Replace mit Buttons. Vergleichbar in der Anzahl Aktionen, aber Mausoperationen statt Tastatur.

Der Vim-Way mit n. hat einen Vorteil, der erst beim zweiten Hinschauen sichtbar wird: du kannst zwischen Stellen entscheiden. Wenn die nächste Stelle nicht ersetzt werden soll, drückst du n (zur übernächsten), nicht .. Wenn dort ein anderer Edit nötig ist, machst du ihn, und ab dann wiederholt . den neuen Edit. Diese Flexibilität in der Mitte eines Massen-Edits hat kein :s-Befehl.

„Make the change easy to repeat"

Eine der zentralen Vim-Designphilosophien lautet: strukturiere Edits so, dass . sie reproduzieren kann. In der Praxis heißt das, einen Edit so kurz und atomar wie möglich zu formulieren — eine einzige Operator-Object-Kombi, gefolgt von Esc, ohne zwischendurch zu navigieren.

Ein konkretes Beispiel — Aufgabe: am Ende jeder Funktions-Zeile soll ein Kommentar // done ergänzt werden. Drei Lösungsansätze:

Variante A: nicht-idiomatisch

text A — bad: viele Tasten pro Iteration
" Cursor in der ersten Funktions-Zeile
$a // done<Esc>      " $ Sprung ans Zeilenende, a für Append, Text, Esc

" Zweite Funktion:
" Cursor manuell zur Zeile bewegen (Motions oder Suche)
$a // done<Esc>      " gleiche Tastenfolge wieder

Drei Probleme: jede Iteration ist 13 Tasten, der Cursor muss neu gesetzt werden, und das $a ist eine zusammengesetzte Sequenz, die nicht als atomarer Edit zählt — . würde nicht funktionieren wie erwartet.

Variante B: idiomatischer

text B — good: A statt $a, kompakter Edit
" Cursor irgendwo in der Zeile
A // done<Esc>       " A = Append am Zeilenende, Text, Esc

" Zur nächsten Funktions-Zeile (mit Suche oder Motion)
]m                   " z. B. nächste Funktion in C/Java
.                    " wiederholt A // done<Esc>
]m
.

A ist ein einzelner Befehl, der „Insert am Zeilenende" als atomare Operation durchführt. A // done<Esc> zählt als ein Edit-Block und ist mit . reproduzierbar — egal wo der Cursor in der Zeile steht.

Variante C: vollständig idiomatisch mit Suche

text C — best: Search-Edit-Repeat
" Mit Suche zur ersten passenden Zeile
/function<CR>         " erste Funktion finden
A // done<Esc>        " am Zeilenende ergänzen

" Loop:
n.                    " nächste Funktion, gleicher Edit
n.
n.

Die Suche tut die Navigation, der Punkt tut den Edit. Zwei Tasten pro Iteration. Das ist der eigentliche Vim-Way — und Variante B/C unterscheiden sich konzeptionell signifikant von A.

Counts mit .

. respektiert Counts auf zwei Arten:

Der ursprüngliche Count wird übernommen

Wenn der letzte Edit einen Count enthielt, wiederholt . mit demselben Count:

text Count wird mitwiederholt
3dw                  " drei Wörter löschen
.                    " noch drei Wörter löschen (insgesamt sechs)

Ein neuer Count überschreibt

Wer vor . einen neuen Count drückt, ersetzt damit den alten:

text Count überschreiben
3dw                  " drei Wörter löschen
5.                   " jetzt FÜNF Wörter löschen (nicht 5×3)
1.                   " jetzt EIN Wort löschen

Das ist eine elegante Bequemlichkeit: ein zu großer ursprünglicher Count lässt sich beim Wiederholen ohne neue Operator-Motion-Eingabe verkleinern oder vergrößern.

Was . NICHT wiederholt

Drei Klassen von Operationen sind außerhalb von .:

Ex-Befehle haben eigene Wiederholungs-Mechanismen

. wiederholt keine Ex-Befehle. :s/foo/bar/ wird nicht durch . reproduziert. Für Ex-Befehle gibt es eigene Repeat-Tasten:

BefehlWiederholung
:s& (gleicher Befehl, ohne Flags) oder :&& (mit gleichen Flags)
:@: führt den letzten Ex-Befehl nochmals aus
//?n (vorwärts) / N (rückwärts) für die Such-Wiederholung
q-Macro@@ wiederholt das letzte ausgeführte Macro

& als Wiederholung für :s ist im Alltag sehr nützlich — eine schnelle Substitution kann mit & auf den nächsten Match in jeder Zeile angewendet werden, ohne den vollen :s-Befehl neu einzutippen.

Reine Motions zählen nicht als Edit

Wer j, gg, f( oder /pattern ausführt, ändert den Buffer nicht — . ignoriert diese Befehle vollständig. Erst der nächste echte Edit wird als „letzte Operation" gespeichert.

Plugin-Befehle: ja-nein-vielleicht

Plugins, die ihre Aktionen über :-Befehle oder Lua/Vimscript-Funktionen ausführen, sind für . per Default unsichtbar. Das gilt z. B. für viele klassische Vim-Operationen aus tpopes Sammlung — :Surround, :Commentary, :GitStatus. Genau dafür gibt es das Plugin vim-repeat, siehe nächster Abschnitt.

vim-repeat — die Brücke für Plugin-Edits

Das Plugin tpope/vim-repeat erweitert . um Plugin-Awareness. Es stellt eine kleine API bereit, mit der Plugins ihre Aktionen als „wiederholbar" markieren können. Sobald vim-repeat installiert ist und ein Plugin diese API nutzt, funktioniert . auch für Plugin-Befehle.

Die wichtigsten Plugins, die vim-repeat voraussetzen:

  • vim-surroundysiw", cs"', ds( werden durch . wiederholbar.
  • vim-commentarygcc, gcap werden wiederholbar.
  • vim-unimpaired — diverse [.../]...-Bindings.
vim ~/.vimrc — Plugins
" Plugin-Setup mit vim-plug
call plug#begin()
Plug 'tpope/vim-repeat'        " Voraussetzung — zuerst!
Plug 'tpope/vim-surround'      " ysiw" und Co.
Plug 'tpope/vim-commentary'    " gcc / gcap
call plug#end()

Ohne vim-repeat würde z. B. ysiw" (mit vim-surround) das innere Wort in Anführungszeichen setzen — und . würde nicht funktionieren wie erwartet, sondern den letzten eingebauten Edit reproduzieren. Mit vim-repeat wird der vim-surround-Befehl als wiederholbar erkannt, und . macht das, was man intuitiv erwartet.

Die Empfehlung ist klar: wer Plugins von tpope (oder im selben Stil) nutzt, sollte vim-repeat als ersten Eintrag in der Plugin-Liste haben.

Übungs-Aufgaben

Wer Dot-Repeat verinnerlichen will, kann ein paar Übungen am eigenen Code probieren:

AufgabeIdiomatischer Vim-Weg
Alle Vorkommen von var durch let ersetzen, einzeln kontrolliert/var<CR>cwlet<Esc>n. × n
Am Ende jedes import-Statements ein ; ergänzen/^import<CR>A;<Esc>n. × n
Drei Wörter pro Zeile uppercase machen, dann eine Zeile weitergU3wj. × n
Bei einer Liste die ersten zwei Klammern aus jeder Zeile entfernendt(j. × n
HTML-Tags in mehreren Zeilen ändern/foo<CR>cit bar<Esc>n. × n

Der gemeinsame Nenner: jeder Edit ist eine kurze, atomare Sequenz, die mit <Esc> endet. Wer den Edit zu komplex baut (mehrere Operator-Motion-Kombis hintereinander, ohne Esc), zerstört die .-Wiederholbarkeit und muss eines der anderen Werkzeuge nutzen (Macro, :s, manuelles Wiederholen).

Besonderheiten

`.` ist Vims einprägsamster Befehl

Ein einzelner Punkt — auf jeder Tastatur leicht erreichbar, kein Modifier, keine Sequenz. Das ist Absicht: Vim's Designer wollten den am häufigsten benötigten Befehl auf die am bequemsten erreichbare Taste legen. Wer dot-repeat wirklich nutzt, drückt diese Taste hunderte Male pro Stunde.

`.` funktioniert auch nach Buffer-Wechseln

Der letzte Edit bleibt gespeichert, auch wenn du in einen anderen Buffer wechselst. dw in file1.txt, dann :b file2.txt, dann . — das löscht ein Wort in der zweiten Datei. Per-Buffer wird der Edit nicht zurückgesetzt.

`@:` ist `.` für Ex-Befehle

Wer :s/foo/bar/g ausgeführt hat und ihn auf eine andere Zeile anwenden will, kann @: drücken — das wiederholt den letzten Ex-Befehl. Mit @@ danach wiederholt sich der gleiche @:-Aufruf. So lässt sich ein Ex-Befehl auf eine ganze Liste von Zielen anwenden.

`:&&` wiederholt `:s` mit gleichen Flags

& allein wiederholt nur das Pattern der letzten Substitution — ohne g-Flag. :&& (Doppel-Ampersand) wiederholt mit den gleichen Flags. Praktisch zum Durchgehen einer Datei: erste Substitution mit Flags, dann auf jeder weiteren Zeile :&&.

Macros sind Dots auf Steroiden

Wenn der zu wiederholende „Edit" mehrere Operator-Motion-Kombis und Bewegungen enthält, geht . nicht mehr. Dort beginnen Macros: qa ... q zeichnet eine Sequenz auf, @a spielt sie ab. Das Konzept wird im Kapitel Editieren fortgeschritten ausführlich behandelt.

`vim-repeat` ist eine Plugin-Voraussetzung, kein eigenes Plugin

Niemand installiert vim-repeat für sich selbst — es bietet keine eigenen Tastenkombinationen. Es ist eine Library, die andere Plugins (vor allem tpope's) zum Funktionieren brauchen. Wer ein tpope-Plugin nutzt und feststellt, dass . nicht wie erwartet wirkt: vim-repeat als ersten Plugin-Eintrag prüfen.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Modi

Zur Übersicht