Über relative Bewegung (h, j, w, f) hinaus hat Vim eine vollständige Familie absoluter Navigation: direkte Zeilen-Sprünge mit gg und G, Screen-Anker wie H/M/L, benannte Marks (lokal ma-mz, global mA-mZ), und zwei automatische Positions-Listen — die Jumplist (jeder größere Sprung wird gespeichert, Ctrl-o führt zurück) und die Changelist (jeder Edit wird gespeichert, g; führt zurück). Diese vier Familien zusammen sind Vims „Zeitreisemaschine": man kann sich beliebig durch eine Datei bewegen und mit einer Taste an die letzte Edit-Stelle, die letzte Sprung-Stelle oder ein benanntes Lesezeichen zurückkehren. Dieser Artikel deckt alle vier ab und zeigt, wie sie zusammen einen Workflow ergeben, der reines Maus-Scrolling weit hinter sich lässt.

Direkte Zeilen-Sprünge

Die einfachsten absoluten Bewegungen:

BefehlBewegung
ggzur ersten Zeile im Buffer
Gzur letzten Zeile im Buffer
NG oder Nggzur Zeile N (z. B. 42G)
:NEx-Variante zur Zeile N (z. B. :42 plus Enter)
:$zur letzten Zeile (Ex-Variante)
N%zu N Prozent der Datei (z. B. 50% = Mitte)

42G und :42<CR> sind funktional identisch — beide springen zur Zeile 42. Wer die Zeile aus einem Compiler-Fehler oder einer Linter-Meldung kennt, ist mit der direkten Eingabe schneller als mit gg plus 41j.

Eine kleine Eigenheit: 0G springt zur letzten Zeile (nicht zu Zeile 0), weil Vim Count 0 nicht als „springe zur Zeile 0" interpretiert. Konsistent mit der Tatsache, dass Zeile 1 die erste ist.

Screen-Anker: H, M, L

Drei Befehle springen zu sichtbaren Positionen auf dem aktuellen Bildschirm:

TasteBewegung
HHigh — zur obersten sichtbaren Zeile
MMiddle — zur mittleren sichtbaren Zeile
LLow — zur untersten sichtbaren Zeile

Mit Count: 5H springt zur fünften Zeile von oben, 5L zur fünften von unten. H/M/L arbeiten relativ zum Bildschirm-Inhalt, nicht zur Datei — was sie zur idealen Wahl macht, wenn man eine Stelle ungefähr sieht, aber nicht die genaue Zeilennummer kennt.

text H/M/L im Editor
Bildschirm zeigt Zeilen 50-100 (aktuelle Ansicht):

  50  ── erste sichtbare Zeile      ← H springt hierhin
  ...
  75  ── mittlere sichtbare Zeile   ← M springt hierhin
  ...
 100  ── letzte sichtbare Zeile     ← L springt hierhin

Eine Plus-Empfehlung: nach Sprüngen mit H/M/L mit zz den Cursor wieder vertikal zentrieren — sonst springt der Bildschirm-Inhalt nicht mit dem Cursor.

Marks: benannte Positionen

Vims Marks sind benannte Cursor-Positionen, die du an beliebige Stellen setzen und später anspringen kannst. Wie kleine Lesezeichen im Buffer.

BefehlAktion
m + KleinbuchstabeMark in aktuellem Buffer setzen (z. B. ma, mb, mc)
m + Großbuchstabeglobale Mark setzen (z. B. mA, mB — File-übergreifend)
` + Buchstabezur exakten Position (Zeile + Spalte) der Mark springen
' + Buchstabezur Zeile der Mark springen (Anfang der Zeile)
:marksalle aktiven Marks auflisten
:delmarks a b cspezifische Marks löschen
:delmarks!alle lokalen Marks (a-z) im aktuellen Buffer löschen

Der wichtige Unterschied: lokale Marks (a-z) gelten nur im aktuellen Buffer und werden in der viminfo pro Buffer gespeichert. Globale Marks (A-Z) gelten datei-übergreifendmA setzt eine Mark, 'A springt von überall dorthin, auch wenn die Datei aktuell nicht geöffnet ist (Vim öffnet sie automatisch).

` vs. ' — Spalte oder nur Zeile

text Backtick vs. Apostroph
Buffer:
    line 1
    line 2 X mark gesetzt mit "ma" — Cursor war an Spalte 8 (X)
    line 3
    line 4

" Nach Navigation zu line 4, Cursor an Spalte 1:
`a    → Sprung zu line 2, Spalte 8 (exakte Position)
'a    → Sprung zu line 2, Spalte 1 (Anfang der Mark-Zeile)

Im Alltag ist ` (Backtick) meist die richtige Wahl — Spalte plus Zeile. ' (Apostroph) ist gelegentlich nützlich, wenn die Spalte irrelevant ist (z. B. wenn man am Zeilenanfang des Lesezeichens anfangen will, egal wo der Cursor beim Setzen war).

Setzen und Springen — typischer Workflow

text Marks im Alltag
" In Funktion foo() arbeiten, kurz Abstecher in bar() machen wollen
ma                  " Mark "a" setzen (aktuelle Position)
/bar<CR>            " zu bar() suchen
" ... etwas anschauen ...
`a                  " zurück zur Mark, exakte Position

Für File-übergreifend:

text Globale Marks
" Im wichtigen File arbeiten:
mF                  " globale Mark "F" setzen

" ... weit später, evtl. in einer anderen Datei, anderem Tab ...
'F                  " Vim öffnet das gemarkte File und springt zur Zeile

Globale Marks sind die schnellste Variante, „Lieblings-Stellen" im Projekt zu markieren — z. B. die Datei mit der Konfiguration, die Hauptfunktion, das Routing-Modul.

Spezial-Marks — automatisch gesetzt

Neben den selbst-gesetzten Marks pflegt Vim eine Reihe automatischer Marks, die du nicht setzen musst — sie entstehen durch Editor-Aktionen:

MarkBedeutung
``Position vor dem letzten Sprung (Two-Backtick)
`.Position des letzten Edits
`^Position, an der zuletzt der Insert-Mode verlassen wurde
`[Anfang des letzten yank, delete oder change
`]Ende des letzten yank, delete oder change
`<Anfang der letzten Visual-Selektion
`>Ende der letzten Visual-Selektion

(zwei Backticks) ist im Alltag besonders nützlich: nach jedem größeren Sprung führt es zurück zur letzten Position. Wer mit `/pattern` woandershin gesprungen ist, kommt mit zurück.

`. springt zur letzten Edit-Position — was bei „wo war ich gerade beim Editieren?"-Workflows den entscheidenden Schritt spart.

text Spezial-Marks im Workflow
" Edit in foo.go, dann Suche im selben Buffer
ciwneuer<Esc>        " Wort ändern
/someOtherWord<CR>    " woanders hin suchen
`.                    " zurück zum letzten Edit
``                    " zurück zur letzten Sprung-Position (vor /)

`[ und `] sind nützlich, um die Grenzen des letzten Yanks oder Delete wieder anzusteuern — etwa um den eben kopierten Bereich erneut zu markieren mit ` [v`].

Die Jumplist

Vims Jumplist ist eine automatisch gepflegte Liste aller größeren Sprünge. Jeder Befehl, der den Cursor um mehr als ein paar Zeichen bewegt, fügt einen Eintrag hinzu. Damit gibt es eine Browser-ähnliche „Zurück"-Funktion durch die Navigation der aktuellen Session.

TasteAktion
Ctrl-oeine Position zurück in der Jumplist
Ctrl-i oder Tabeine Position vorwärts
:jumpsalle Einträge der Jumplist anzeigen
:clearjumpsJumplist leeren

Welche Befehle einen Jumplist-Eintrag erzeugen:

  • Zeilen-Sprünge: gg, G, NG, :N
  • Suche: /, ?, n, N, *, #
  • Marks: `, '
  • Semantische Motions: (, ), {, }, [[, ]], [m, ]m
  • Tag-Sprünge: <C-]>, <C-t>
  • Buffer-Wechsel: <C-^>, :b

Nicht in der Jumplist (zu klein-skalig):

  • Zeichen-Motions: h, j, k, l, w, b, e
  • Insert-Mode-Eintritt
text Jumplist-Workflow
" Verschiedene Sprünge im Buffer
gg                   " Position A (Buffer-Anfang) — in Jumplist
/foo<CR>             " Position B (erstes "foo") — in Jumplist
}                    " Position C (nächster Absatz) — in Jumplist
50G                  " Position D (Zeile 50) — in Jumplist

<C-o>                " zurück nach C
<C-o>                " zurück nach B
<C-o>                " zurück nach A
<C-i>                " wieder vorwärts nach B

:jumps zeigt die Liste mit Position und Datei:

text :jumps-Ausgabe
:jumps
Output
 jump line  col file/text
   4    42    0 src/foo.go
   3   158    7 var name = getName()
   2    77    0 src/bar.go
   1    23   15 } else if (...)
>  0    50    0 src/baz.go

Das > markiert die aktuelle Position. Negative Indices waren noch nicht gesprungen, positive sind bereits per Ctrl-o zurückgekehrte Positionen.

Die Jumplist überdauert die Session nicht automatisch — sie ist Per-Window und wird beim Vim-Beenden geleert (es sei denn, viminfo wurde explizit dafür konfiguriert).

Die Changelist

Parallel zur Jumplist führt Vim eine Changelist — eine Liste aller Edit-Positionen.

TasteAktion
g;eine Edit-Position zurück in der Changelist
g,eine Edit-Position vorwärts
:changesalle Edit-Positionen anzeigen

Der Unterschied zur Jumplist:

  • Jumplist speichert Sprung-Ursprünge (wo war ich, bevor ich gesprungen bin?).
  • Changelist speichert Edit-Ziele (wo habe ich was geändert?).

g; ist die Antwort auf „wo habe ich gerade nochmal was geändert?". Bei drei verstreuten Edits im selben Buffer führt g; jeweils einen Schritt zurück:

text Changelist-Workflow
" Edits an drei verschiedenen Stellen:
50G ciw NEU<Esc>     " Edit 1 in Zeile 50
100G ciw NEU<Esc>     " Edit 2 in Zeile 100
200G ciw NEU<Esc>     " Edit 3 in Zeile 200

" Jetzt: wo war der erste Edit?
g;                   " zurück zu Edit 2 (Zeile 100)
g;                   " zurück zu Edit 1 (Zeile 50)
g,                   " vorwärts zu Edit 2

Anders als die Jumplist ist die Changelist per Buffer — jeder Buffer hat seine eigene.

Zusammenspiel: vier Navigations-Schichten

Vim hat damit vier komplementäre absolute Navigations-Schichten:

SchichtWie gepflegtWomit zurückReichweite
Zeilen-Sprüngemanuell mit :N, NGnichts spezifischaktueller Buffer
Marksmanuell mit m{a-z}` + BuchstabeBuffer oder global
Jumplistautomatisch bei Sprüngen<C-o> / <C-i>Window (mehrere Buffer)
Changelistautomatisch bei Editsg; / g,Buffer

In der Praxis nutzt man alle vier Schichten je nach Kontext:

  • Bekannte Zielzeile42G oder :42
  • Mehrere semantisch wichtige Stellen → globale Marks mA/mB
  • „Wo war ich gerade?"<C-o> (Sprung-zurück)
  • „Wo hatte ich gerade was geändert?"g; (Edit-zurück)

Wer diese vier Reflexe verinnerlicht hat, navigiert in großen Codebases ohne Maus, ohne Tab-Wechsel und ohne Page Up/Page Down.

Praxis-Workflows

Drei typische Anwendungs-Szenarien:

Workflow 1: Refactoring an drei Stellen

text Workflow 1
" Drei Stellen sollen koordiniert geändert werden
ma                   " Mark "a" am ersten Edit-Punkt
" ... navigieren zum zweiten ...
mb                   " Mark "b"
" ... navigieren zum dritten ...
" Edit hier ausführen
`b                   " zurück zur zweiten Mark
" Edit
`a                   " zurück zur ersten
" Edit

Workflow 2: Kurz nachschlagen, dann weiter

text Workflow 2
" Mitten in der Arbeit, kurz Funktion-Signatur prüfen
" (Cursor steht in Zeile 200, prüft Funktion in Zeile 50)

/functionFoo<CR>     " zur Funktion springen (Jumplist-Eintrag)
" ... Signatur lesen ...
<C-o>                " zurück zur Arbeit (Zeile 200)

Schneller als :set number + manuell zur Zeile springen.

Workflow 3: Globale Marks für Projekt-Anker

text Workflow 3
" In jeder wichtigen Datei einmalig eine globale Mark setzen
:e src/main.go
mM                   " M = Main

:e src/router.go
mR                   " R = Router

:e src/config.go
mC                   " C = Config

" Im Alltag, von beliebiger Stelle aus:
'M                   " sofort in src/main.go
'R                   " sofort in src/router.go
'C                   " sofort in src/config.go

Globale Marks sind in der viminfo persistent — sie überdauern Vim-Restarts und sind nach dem Neuöffnen wieder verfügbar.

Besonderheiten

`` `` `` ist die wichtigste Spezial-Mark

Zwei Backticks springen zur letzten Position vor dem letzten Sprung. Damit hat man eine „Undo"-Variante für jede //G/}-Bewegung — ein einzelner Tastendruck zurück zur vorherigen Position. Sehr häufig der genau richtige Befehl im Alltag.

`` und `` `` `` sind ähnlich, aber nicht identisch

<C-o> geht eine Position zurück in der Jumplist — kann je nach Historie verschiedene Sprünge umfassen. `` springt genau zur Position vor dem letzten Sprung. Bei einer einzigen Sprung-Aktion sind beide identisch; bei mehreren hintereinander divergieren sie.

`H`/`M`/`L` plus `zz` als Reflex

Nach einem H/M/L-Sprung bleibt der Cursor an der Bildschirm-Position — sinnvoll, weil man die Stelle eh sah. Wer den Cursor nach dem Sprung vertikal zentriert haben will, hängt zz an: Hzz, Mzz, Lzz.

Globale Marks (A-Z) überdauern Vim-Restarts

Über viminfo werden globale Marks gespeichert. Nach mF und Vim-Neustart funktioniert 'F weiterhin — Vim öffnet die markierte Datei und springt zur Position. Praktisch für ein paar Hand-voll wichtiger Projekt-Anker.

`:delmarks!` betrifft NUR lokale Marks

Die Variante mit Bang löscht alle a-z-Marks im aktuellen Buffer. Globale Marks (A-Z) bleiben erhalten — dafür :delmarks A B C einzeln aufrufen oder :delmarks A-Z für alle.

Jumplist ist Window-spezifisch, nicht Buffer-spezifisch

Jeder Window hat seine eigene Jumplist. Bei :split erbt das neue Fenster die Liste vom alten, ab dann pflegen beide unabhängig. Die Changelist hingegen ist Buffer-spezifisch — gilt überall, wo der Buffer angezeigt wird.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Navigation

Zur Übersicht