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:

TasteWas 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:

BefehlBedeutung
:waktuellen Buffer speichern
:w filenameaktuellen Buffer unter neuem Namen speichern
:waalle modifizierten Buffer speichern
:qbeenden (falls nichts ungespeichert ist)
:q!beenden, ungespeicherte Änderungen verwerfen
:wq / :xspeichern und beenden
:qa / :qa!alle Buffer/Fenster beenden
:e filenameDatei öffnen (im aktuellen Fenster)
:e!aktuelle Datei neu von Platte laden, Änderungen verwerfen
:b namezu Buffer mit passendem Namen wechseln
:lsalle offenen Buffer auflisten
:vsplit filenamevertikalen Split mit neuer Datei öffnen
:split filenamehorizontalen Split mit neuer Datei öffnen
:set optionOption setzen (:set number, :set ignorecase)
:set option?aktuellen Wert einer Option anzeigen
:!commandShell-Befehl ausführen (:!ls, :!git status)
:r filenameInhalt einer Datei an Cursor-Position einfügen
:r !commandOutput eines Shell-Befehls einfügen
:s/foo/bar/gin aktueller Zeile alle foo durch bar ersetzen
:%s/foo/bar/gim gesamten Buffer alle foo durch bar ersetzen
:nohSuch-Highlight ausschalten

Ein paar der häufigsten Befehle haben Kurzformen, die in der Praxis schneller tippbar sind:

  • :w ist kurz für :write
  • :q für :quit
  • :e für :edit
  • :s für :substitute
  • :b für :buffer
  • :r für :read
  • :so fü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.

RangeBedeutung
.die aktuelle Zeile (Default für viele Befehle)
$die letzte Zeile im Buffer
1die erste Zeile
10,20Zeile 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,'bvon Mark a bis Mark b
.+5fünf Zeilen unterhalb der aktuellen
.-3,.+3drei Zeilen darüber bis drei Zeilen darunter
/pattern/nächste Zeile mit pattern als Startpunkt

Praktische Beispiele:

text Ranges in Aktion
:%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ügen

Die 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:

text Tab-Completion-Beispiele
: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 :substitute

Mit 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:

vim ~/.vimrc
" Bessere Command-Line-Completion
set wildmenu                  " sichtbare Auswahl-Leiste
set wildmode=longest:full,full " erst längstes gemeinsames Präfix, dann durchzyklieren

History — 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:

TasteBedeutung
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:

text q: in Aktion
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ühren

Analog 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:

TokenBedeutung
%aktueller Dateiname (mit Pfad)
%:taktueller Dateiname (ohne Pfad)
%:hVerzeichnis der aktuellen Datei
%:rDateiname ohne Extension
%:eExtension
#letzter Buffer (alternate file)
<cword>das Wort unter dem Cursor
<cWORD>das WORD (Whitespace-getrennt) unter dem Cursor
<cfile>Dateiname unter dem Cursor
text Sonderzeichen-Beispiele
:!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 suchen

Mit 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:

text Shell-Aufrufe aus Vim
:!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 aufrufen

Der 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:

text Output einlesen
: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ügen

Mit 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:

TrennerBedeutung
&#124;Befehle hintereinander ausführen (analog zum Pipe-Zeichen, aber NICHT als Pipe!)
:executeBefehl als Expression evaluieren — für Variablen oder Logik
text Befehls-Verkettung
" 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

Verwandte Artikel

/ Weiter

Zurück zu Bedienkonzept

Zur Übersicht