Wenn Normal-Mode die Hand am Steuer ist und Insert-Mode der eigentliche Schreib-Akt, dann ist der Command-Line-Mode das Cockpit: hier landen alle Befehle, die nicht über einzelne Tasten ausdrückbar sind — Datei speichern, projektweit ersetzen, Plugins steuern, Shell-Aufrufe ausführen, Konfiguration umschalten. Die Sprache, die hier gesprochen wird, ist die alte ex-Sprache aus den 1970er Jahren — Vims direkter Vorfahre ex war ein zeilenorientierter Editor, und seine Befehle leben in jedem :w, :q und :s weiter. Wer die Command-Line beherrscht, erschließt sich Vims zweite Befehlsebene neben der Normal-Mode-Grammatik: Range-basierte Operationen, der :global-Befehl, Volltext-Ersetzung mit :substitute, History-Navigation, das wenig bekannte q:-Fenster für Befehls-Editing — und die Brücke zur Shell mit :!.
Vier Türen in den Command-Line-Mode
Vim hat nicht nur eine, sondern vier Eingänge in den Command-Line-Mode, je nachdem, was man dort tun will:
| Taste | Was passiert |
|---|---|
| : | Ex-Befehl eingeben (:write, :quit, :s/foo/bar/g, :!ls) |
| / | Vorwärts-Suche im Buffer (/pattern) |
| ? | Rückwärts-Suche im Buffer (?pattern) |
| ! | Shell-Filter — gilt nur in Visual-Mode oder nach Motion (!sort, !awk) |
In allen vier Fällen wandert der Cursor in die unterste Zeile, die zur eigentlichen Eingabe-Zeile wird. Du tippst deinen Befehl, schließt mit Enter ab und Vim führt ihn aus. Mit Esc oder Ctrl-c brichst du ab, ohne den Befehl auszuführen.
Während des Tippens funktioniert die Command-Line wie eine Mini-Shell: Backspace löscht, Pfeiltasten gehen durch die History (oder die Buchstaben-Folge), Tab vervollständigt. Mehr dazu in den folgenden Abschnitten.
Die wichtigsten Ex-Befehle
Die alltäglichsten Ex-Befehle sind Datei- und Buffer-Operationen. Vims :help index.txt listet die vollständige Sprache; für die ersten Tage reicht ein kleiner Kernsatz:
| Befehl | Bedeutung |
|---|---|
:w | aktuellen Buffer speichern |
:w filename | aktuellen Buffer unter neuem Namen speichern |
:wa | alle modifizierten Buffer speichern |
:q | beenden (falls nichts ungespeichert ist) |
:q! | beenden, ungespeicherte Änderungen verwerfen |
:wq / :x | speichern und beenden |
:qa / :qa! | alle Buffer/Fenster beenden |
:e filename | Datei öffnen (im aktuellen Fenster) |
:e! | aktuelle Datei neu von Platte laden, Änderungen verwerfen |
:b name | zu Buffer mit passendem Namen wechseln |
:ls | alle offenen Buffer auflisten |
:vsplit filename | vertikalen Split mit neuer Datei öffnen |
:split filename | horizontalen Split mit neuer Datei öffnen |
:set option | Option setzen (:set number, :set ignorecase) |
:set option? | aktuellen Wert einer Option anzeigen |
:!command | Shell-Befehl ausführen (:!ls, :!git status) |
:r filename | Inhalt einer Datei an Cursor-Position einfügen |
:r !command | Output eines Shell-Befehls einfügen |
:s/foo/bar/g | in aktueller Zeile alle foo durch bar ersetzen |
:%s/foo/bar/g | im gesamten Buffer alle foo durch bar ersetzen |
:noh | Such-Highlight ausschalten |
Ein paar der häufigsten Befehle haben Kurzformen, die in der Praxis schneller tippbar sind:
:wist kurz für:write:qfür:quit:efür:edit:sfür:substitute:bfür:buffer:rfür:read:sofür:source
Die Langform ist nie verkehrt — sie funktioniert immer und ist in der Hilfe der referenzierte Name.
Ranges — auf welche Zeilen wirkt der Befehl
Eine Besonderheit der ex-Sprache ist die Range-Syntax: vor dem eigentlichen Befehl gibt man an, auf welchen Zeilenbereich er wirken soll. Ohne Range wirkt der Befehl auf die aktuelle Zeile (bei :s) oder auf den gesamten Editor-Zustand (bei :w, :q). Mit Range kannst du gezielt einen Teilbereich auswählen.
| Range | Bedeutung |
|---|---|
. | die aktuelle Zeile (Default für viele Befehle) |
$ | die letzte Zeile im Buffer |
1 | die erste Zeile |
10,20 | Zeile 10 bis Zeile 20 |
.,$ | aktuelle Zeile bis zum Buffer-Ende |
1,. | erste Zeile bis aktuelle Zeile |
% | alle Zeilen im Buffer (gleich 1,$) |
'<,'> | aktuelle Visual-Selektion (wird automatisch eingefügt) |
'a,'b | von Mark a bis Mark b |
.+5 | fünf Zeilen unterhalb der aktuellen |
.-3,.+3 | drei Zeilen darüber bis drei Zeilen darunter |
/pattern/ | nächste Zeile mit pattern als Startpunkt |
Praktische Beispiele:
:%s/foo/bar/g " ALLE foo → bar (im ganzen Buffer)
:10,20s/foo/bar/g " nur in Zeile 10-20
:.,+5d " aktuelle Zeile und die nächsten 5 löschen
:'<,'>sort u " sortiere die Visual-Selektion und entferne Duplikate
:1,.d " alles oberhalb (inklusive) der aktuellen Zeile löschen
:$put =strftime('%Y-%m-%d') " heutiges Datum an Datei-Ende einfügenDie Range-Syntax ist eine eigene kleine Sprache und braucht Übung — aber sie ist auch der Hebel, warum Vim für Massen-Edits konkurrenzlos ist. Wer :%s/foo/bar/g versteht, kann das gleiche Werkzeug ohne weiteres Lernen auf 100 oder 100 000 Zeilen anwenden.
Tab-Completion in der Command-Line
Vim macht das Tippen langer Ex-Befehle mit eingebauter Tab-Completion angenehm. Während du tippst, vervollständigt Tab Befehle, Dateinamen, Optionen, Buffer-Namen und Help-Tags:
:colors <Tab> " vervollständigt installierte Colorschemes
" → :colors default → :colors industry → ...
:set num <Tab> " vervollständigt Optionsnamen
" → :set number → :set numberwidth → ...
:e src/com<Tab> " vervollständigt Pfade/Dateinamen wie in der Shell
" → :e src/components/Header.tsx
:b cont<Tab> " findet offene Buffer mit "cont" im Namen
" → :b containers/main.go
:help :su<Tab> " Help-Tags vervollständigen
" → :help :substituteMit Ctrl-d bekommst du alle möglichen Vervollständigungen auf einmal angezeigt, statt durch sie zu zyklieren — analog zur Bash. Das ist besonders nützlich bei Help-Tags und Optionsnamen, wenn man nicht weiß, was zur Auswahl steht.
Die Option wildmenu (in modernen Vim-Configs Default) macht die Completion sichtbar als horizontale Auswahl-Leiste oberhalb der Command-Line:
" Bessere Command-Line-Completion
set wildmenu " sichtbare Auswahl-Leiste
set wildmode=longest:full,full " erst längstes gemeinsames Präfix, dann durchzyklierenHistory — Befehle wiederfinden
Vim merkt sich die letzten 20 (Default, anpassbar mit set history=) Ex-Befehle und die letzten 20 Suchen. Durch die History kommst du auf zwei Wegen:
Lineare Navigation mit Pfeil/Ctrl-p
Während der Command-Line-Mode aktiv ist:
| Taste | Bedeutung |
|---|---|
| Ctrl-p / ↑ | vorheriger History-Eintrag |
| Ctrl-n / ↓ | nächster History-Eintrag |
Eine sehr nützliche Erweiterung: Wenn du schon einige Zeichen getippt hast, wirken <C-p>/<C-n> nur auf Einträge, die mit diesen Zeichen beginnen. :s + Ctrl-p blättert durch alle vergangenen :s-Befehle.
Das q:-Fenster — History als editierbarer Buffer
Das wenig bekannte q:-Fenster öffnet die komplette Command-Line-History als normalen Buffer. Du landest in einem horizontalen Split mit einer Liste deiner letzten Befehle und kannst dich mit normalen Motions darin bewegen, einen Befehl editieren und mit Enter ausführen:
q: " History-Fenster öffnen
" (Cursor steht in der Liste der letzten Ex-Befehle)
k " einen Eintrag nach oben gehen
ciw NEU<Esc> " den Befehl editieren wie normalen Text
<Enter> " den editierten Befehl ausführenAnalog gibt es q/ für die Such-History und q? für die Rückwärts-Such-History. Wer regelmäßig komplexe :s-Befehle oder Such-Patterns wiederverwendet und anpasst, hat hier das beste Werkzeug überhaupt — alle Vim-Editing-Möglichkeiten gelten auf die History selbst.
Das q:-Fenster wird mit :q oder Ctrl-c geschlossen.
Sonderzeichen und Variablen in der Command-Line
Innerhalb des Command-Line-Mode gibt es eine kleine Sammlung von Sonderzeichen, die zur Laufzeit ersetzt werden. Die wichtigsten:
| Token | Bedeutung |
|---|---|
% | aktueller Dateiname (mit Pfad) |
%:t | aktueller Dateiname (ohne Pfad) |
%:h | Verzeichnis der aktuellen Datei |
%:r | Dateiname ohne Extension |
%:e | Extension |
# | letzter Buffer (alternate file) |
<cword> | das Wort unter dem Cursor |
<cWORD> | das WORD (Whitespace-getrennt) unter dem Cursor |
<cfile> | Dateiname unter dem Cursor |
:!cat % " den aktuellen Buffer durch cat schicken
:w %:r.bak " als <name>.bak speichern (ohne Extension dranhängen)
:e %:h/sibling.txt " Datei im selben Verzeichnis öffnen
:s/\<<cword>\>/NEW/g " das Wort unter Cursor durch NEW ersetzen
:!grep <cword> *.go " in allen .go-Dateien nach dem Wort suchenMit Ctrl-r kannst du in der Command-Line zusätzlich den Inhalt eines Registers einfügen — analog zum Insert-Mode. Beispiel: :s/<C-r>"/NEU/g ersetzt das, was du zuletzt gelöscht hast, durch „NEU".
Shell-Brücke: :!command und :r !command
Über :! lässt sich jeder Shell-Befehl ausführen, ohne Vim zu verlassen:
:!ls -la " Shell-Befehl, Output erscheint kurz
:!git status " git status für das aktuelle Repo
:!python3 % " aktuelle Datei mit Python ausführen
:!make test " den make-Test-Target aufrufenDer Befehl läuft synchron — Vim wartet auf das Ende und zeigt anschließend „Press ENTER or type command to continue". Für asynchrone Jobs gibt es seit Vim 8 das eingebaute Job-System (:help job), aber :! bleibt die einfachste Variante für „schnell mal etwas checken".
Soll der Output in den Buffer, statt nur angezeigt zu werden, ist :r !command der Weg:
:r !date " heutiges Datum an Cursor-Position einfügen
:r !ls " Verzeichnisliste in den Buffer einfügen
:r !curl -s https://api.ipify.org " externe IP einfügenMit einer Visual-Selektion plus :!command (oder einfacher: Visual-Mode + !) wird der Selektions-Inhalt durch den Shell-Befehl gefiltert — z. B. !sort -u für eine markierte Liste. Diese Variante ist im Visual-Mode-Artikel ausführlich behandelt.
Mehrere Ex-Befehle hintereinander
Manchmal will man zwei Ex-Befehle in einer Zeile verketten. Vim hat zwei Wege:
| Trenner | Bedeutung |
|---|---|
| | Befehle hintereinander ausführen (analog zum Pipe-Zeichen, aber NICHT als Pipe!) |
:execute | Befehl als Expression evaluieren — für Variablen oder Logik |
" Drei Befehle hintereinander
:w | bnext | redraw
" Mit Expression: dynamischer Dateiname
:execute "edit " . expand("~/.vimrc")
" In Mappings besonders wichtig: <bar> als wörtliches | maskieren
nnoremap <leader>x :w <bar> bnext<CR>Wer : in Mappings nutzt, sollte das <CR> am Ende nicht vergessen — sonst landet die Tastenfolge nur in der Command-Line, ohne ausgeführt zu werden.
Interessantes
`:` ist Sprung-Werkzeug, kein Dialog-Fenster
Anfänger empfinden den Wechsel in die Command-Line manchmal als „Aussteigen aus Vim". Tatsächlich ist die Command-Line nur eine andere Eingabe-Spur — Vim ist weiter aktiv, du bist nur in einem Modus, in dem du einen Befehl tippst. Wer : reflexhaft mit „Dialog öffnet sich" assoziiert, sollte die Brille kurz wechseln: es ist Tippen wie im Insert-Mode, nur in der Command-Line statt im Buffer.
Range ohne Befehl springt zur Zeile
Eine Besonderheit: :42<CR> (Zeilennummer ohne Befehl) springt zur Zeile 42. Das ist dieselbe Logik wie 42G im Normal-Mode — aber wer im Kopf eine bestimmte Zeilennummer hat, tippt : und die Nummer oft schneller als 42G. Gilt analog für :$ (Buffer-Ende) und :1 (Anfang).
`q:` ist nicht dasselbe wie `:q`
Häufige Verwechslung: q: öffnet das History-Fenster (im Normal-Mode), :q beendet Vim (im Command-Line-Mode). Erstes ist q gefolgt von :, zweites ist : gefolgt von q. Wer aus Versehen ins History-Fenster gerät und nicht weiß, wo er ist: einfach :q (oder <C-c>) zum Schließen.
`:s` ohne Argumente wiederholt die letzte Substitution
Tippt man nur :s (oder & im Normal-Mode), wiederholt Vim die letzte :substitute-Operation auf die aktuelle Zeile — aber ohne Flags. :s//~/& setzt die letzten Flags ebenfalls. Mit :&& wiederholt Vim mit identischen Flags. Praktisch zum Durchgehen einer Datei: erste Ersetzung mit Flags, dann immer wieder :&&.
Range mit normalen Befehlen — :normal als Brücke
:5,15normal! dw führt den Normal-Mode-Befehl dw in jeder Zeile von 5 bis 15 aus. Das ! nach normal ist wichtig — es verhindert, dass Mappings den Befehl umlenken. Damit hast du die volle Normal-Mode-Sprache auf einen Range angewendet — eine der mächtigsten Vim-Idiome.
`:up` statt `:w` — speichern nur, wenn nötig
:w schreibt die Datei immer, auch wenn nichts geändert wurde — das aktualisiert die mtime, was Build-Tools und File-Watcher triggern kann. :up (kurz für :update) schreibt nur bei tatsächlichen Änderungen. Empfehlung für Mappings: nnoremap <leader>w :update<CR> statt :w<CR>.
Weiterführende Ressourcen
Externe Quellen
- Vim Help: Command-Line-Mode — formale Definition.
- Vim Help: ex-cmd-index — alphabetische Liste aller Ex-Befehle.
- Vim Help: cmdline-ranges — vollständige Range-Syntax.
- Vim Help: cmdline-special — Sonderzeichen wie %, #, <cword>.
- Vim Help: q: — das Command-Line-Fenster.