Über hjkl (Zeichen), w/b (Wort) und 0/$ (Zeile) hinaus hat Vim eine eigene Familie semantischer Motions — Sprünge, die strukturelle Einheiten des Texts erkennen. Ein Satz endet in Vim an ., ! oder ? (gefolgt von Whitespace); ein Absatz an einer Leerzeile; eine Top-Level-Section bei C-artigem Code an einer geschweiften Klammer in Spalte 1; eine Methode bei den meisten Sprachen an der Methode-Signatur. Diese Motions sind oft die schnellste Variante, um sich strukturell im Code oder in Prosa zu bewegen — fünf Absätze nach unten in einer Markdown-Datei ist 5}, zur nächsten Funktion in einer C-Datei ist ]]. Dieser Artikel deckt vier Motion-Familien ab, zeigt typische Operator-Kombinationen und erklärt die Grenzen — welche Filetypes sie sauber unterstützen und welche nicht.

Sätze: ( und )

Vims Satz-Motions springen zwischen Satz-Grenzen. Ein Satz endet in Vims Definition an einem Punkt, Ausrufezeichen oder Fragezeichen, gefolgt von einem Zeilenende oder einem oder mehreren Leerzeichen.

TasteBewegung
(zum Anfang des aktuellen oder vorherigen Satzes
)zum Anfang des nächsten Satzes
text Satz-Motion an Prosa
Buffer:  Das ist Satz eins. Das ist Satz zwei! Und Satz drei? Vier.
         ^

Cursor am Zeilenanfang (Buchstabe D von "Das"):

  )  → Cursor auf "D" von "Das ist Satz zwei!"
  )  → Cursor auf "U" von "Und Satz drei?"
  )  → Cursor auf "V" von "Vier."
  (  → einen Satz zurück

Im Code-Workflow sind die Satz-Motions selten direkt nützlich (Code besteht meist nicht aus „Sätzen"), in Markdown- und Prosa-Workflows aber zentral: ein einzelner ( oder ) springt präzise zwischen Sätzen, ohne die Zeile zu kennen.

Absätze: { und }

Die Absatz-Motions sind nützlicher und vielseitiger. Ein Absatz endet bei einer Leerzeile.

TasteBewegung
{zum Anfang des aktuellen oder vorherigen Absatzes
}zum Ende des aktuellen Absatzes (= nächste Leerzeile)
text Absatz-Motion an strukturiertem Text
Buffer:  Erster Absatz mit
         zwei Zeilen.
                               ← Leerzeile = Absatz-Grenze
         Zweiter Absatz.
                               ← Leerzeile
         Dritter Absatz, der
         sich über drei
         Zeilen erstreckt.

Cursor in Zeile 1:

  }  → Cursor auf die Leerzeile nach "zwei Zeilen."
  }  → Cursor auf die Leerzeile nach "Zweiter Absatz."
  }  → Cursor auf die letzte Zeile (oder Leerzeile danach)
  {  → einen Absatz zurück

Counts funktionieren: 5} springt fünf Absätze weiter. In langen Markdown-Dateien oder strukturiertem Plain-Text ist das die effizienteste Navigations-Form überhaupt — schneller als Page Down, präziser als zählen mit j.

Operator-Kombinationen mit Absatz-Motions sind sehr alltäglich:

BefehlAktion
d}lösche bis zum Absatz-Ende (vom Cursor bis nächste Leerzeile)
y}kopiere bis Absatz-Ende
c}ändere bis Absatz-Ende
>}rücke Absatz ein (vom Cursor abwärts)
gq}reformatiere bis Absatz-Ende
daplösche around paragraph (Text-Object — siehe Kapitel 8)
diplösche inner paragraph

gqap (reformatiere den ganzen Absatz) ist beim Schreiben von Markdown- und Code-Kommentaren ein Klassiker — Vim umbricht den Absatz auf die textwidth-Spalte.

Top-Level-Sections: [[, ]], [], ][

Bei C-artigen Sprachen (C, C++, Java, Go, Rust, JavaScript) erkennt Vim Top-Level-Funktions-Definitionen an einer öffnenden geschweiften Klammer in Spalte 1. Vier Motions navigieren zwischen ihnen:

TasteBewegung
[[rückwärts zum Anfang der vorigen Top-Level-Section
]]vorwärts zum Anfang der nächsten Top-Level-Section
[]rückwärts zum Ende der vorigen Top-Level-Section
][vorwärts zum Ende der aktuellen oder nächsten Top-Level-Section
text Top-Level-Section-Motion in C
Buffer (C-Code):
    int foo() {
        return 1;
    }
                                 ← Leerzeile

    int bar() {
        return 2;
    }
                                 ← Leerzeile

    int baz() {
        return 3;
    }

Cursor irgendwo in foo():

  ]]  → Cursor auf "int bar()"   (Anfang der nächsten Top-Level-Funktion)
  ]]  → Cursor auf "int baz()"
  [[  → einen Schritt zurück (zu "int bar()")
  ][  → ans Ende der aktuellen Section (`}` von bar)

Das funktioniert allerdings nur, wenn die öffnende Klammer in Spalte 1 steht — die ältere C-Stil-Konvention. Bei moderneren Stilen, wo die Klammer am Funktionsnamen klebt (int foo() { ohne Newline davor), greifen [[/]] nicht wie erwartet. Für moderne Sprachen sind die Method-Motions ([m/]m, nächster Abschnitt) zuverlässiger.

Methoden: [m, ]m, [M, ]M

Die Method-Motions sind die moderne, sprach-übergreifende Variante:

TasteBewegung
[mrückwärts zum Anfang der vorigen Methode
]mvorwärts zum Anfang der nächsten Methode
[Mrückwärts zum Ende der vorigen Methode
]Mvorwärts zum Ende der aktuellen oder nächsten Methode

Im Default funktionieren diese vier Motions für Sprachen mit der C-typischen { }-Blockstruktur — Java, JavaScript, Go, C#, Kotlin, Rust und ähnliche. Vim erkennt die nächste Block-Öffnung als „Methoden-Start" und springt dorthin.

text Method-Motion in JavaScript
Buffer (JavaScript):
    class User {
        constructor(name) {
            this.name = name;
        }

        greet() {
            return `Hello, ${this.name}`;
        }

        farewell() {
            return "Bye";
        }
    }

Cursor in constructor:

  ]m  → Cursor auf "greet()"      (Anfang der nächsten Methode)
  ]m  → Cursor auf "farewell()"
  [m  → einen Schritt zurück
  ]M  → Ende der aktuellen Methode (`}`)

Für Sprachen ohne { }-Block-Struktur (Python, Ruby, Lua, Haskell, Lisp) funktionieren die eingebauten Method-Motions nicht zuverlässig — sie brauchen filetype-spezifische Plugins oder Tree-sitter-basierte Motions (siehe Plugin-Hinweis weiter unten).

% — die Match-Klammer-Motion

Eine verwandte, aber eigenständige Motion: % springt zwischen passenden Klammern:

Cursor aufSprung mit % zu
(passendem )
)passendem (
[passendem ]
{passendem }
/* … */Kommentar-Anfang / -Ende
#if/#endifpassendem Präprozessor-Block (in C)

% ist die schnellste Variante, um durch verschachtelte Strukturen zu navigieren: in einer JSON-Datei mit drei Ebenen Verschachtelung springt % von der äußeren { direkt zur passenden } am Ende — egal wie weit dazwischen.

Mit Operatoren ergibt das mächtige Edits:

text % mit Operatoren
" Cursor auf der äußeren { eines JSON-Objekts
d%       " lösche das gesamte Objekt von { bis }
y%       " kopiere die gesamte Klammer-Region
v%       " markiere die gesamte Region für weitere Operation

Das matchit-Plugin (in modernen Vim-Versionen Default) erweitert % auf zusätzliche Paare wie HTML-Tags, if/endif, do/end, def/end etc. — sprach-spezifisch und sehr nützlich.

Tree-sitter-basierte Funktions-Motions für Vim

Vims eingebaute Method-Motions sind C-artig und decken Python, Ruby, Lisp und Co. nicht ab. Für sprachbewusste Funktions-Sprünge gibt es zwei Plugin-Wege:

vim-textobj-function

vim-textobj-function definiert Text-Objects if und af (inner/around function), die das gesamte Funktions-Konstrukt als Bereich verstehen — egal in welcher Sprache (mit installierten Sprach-Definitionen). Damit funktionieren Befehle wie:

text vim-textobj-function in Aktion
daf      " delete around function (komplette Funktion)
cif      " change inner function (Funktions-Körper)
yaf      " yank around function

coc-pyright / sprach-spezifische LSP-Plugins

Wer ohnehin coc.nvim für LSP nutzt, hat über <Plug>(coc-funcobj-i)/<Plug>(coc-funcobj-a) und ähnliche LSP-basierte Motions Zugriff auf semantische Funktions-Sprünge — auf Basis des LSP-Servers, also sprach-genau. Die Konfiguration:

vim ~/.vimrc — coc-funcobj-Mappings
" coc.nvim Funktions-Objekt-Mappings (klassisch i und a)
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)

Damit kann daf in Python eine Funktion löschen, in Ruby eine def/end-Region und in Lisp ein defun-Konstrukt — alles über dieselbe Tastenkombination.

Wann welche Motion

Eine Faustregel zur Wahl:

AufgabeBeste Motion
In Prosa zum nächsten Satz) oder (
In Markdown zum nächsten Absatz&#125; (oder &#123; rückwärts)
Zur nächsten Methode in JavaScript/Go/Java]m
Zur nächsten Top-Level-Funktion in C (Klammer in Sp 1)]]
Innerhalb eines Code-Blocks zur passenden }%
In Python zur nächsten MethodePlugin (coc-funcobj, treesitter-textobjects in Neovim)
Über mehrere Zeilen einen Bereich auswählenvap (Absatz) oder vi&#123; (innerhalb Block)

Wer in einer Sprache arbeitet, deren Method-Motions eingebaut funktionieren, hat in vier Tasten (]m, [m, ]], [[) eine schnelle Navigation. Für andere Sprachen lohnt sich die einmalige Plugin-Installation.

Praxis-Workflows

Drei typische Anwendungs-Szenarien:

Workflow 1: Markdown-Datei strukturell durchgehen

text Workflow 1
" Lange Markdown-Datei mit vielen Absätzen
gg                     " an den Anfang
}                      " zum Ende des ersten Absatzes (= Leerzeile)
}                      " zum nächsten Absatz-Ende
}                      " weiter
" ... oder direkt:
5}                     " fünf Absätze nach unten

Schneller als <C-d> (halbe Seite) und präziser als j × 20.

Workflow 2: Eine Funktion löschen und woanders einfügen

text Workflow 2
" JavaScript-Datei: Funktion soll an eine andere Stelle
" Cursor irgendwo in der Funktion

[m                     " zum Anfang der Methode springen
v]M                    " visual bis ans Ende der Methode markieren
d                      " löschen (landet im Register)
" ... zum Ziel navigieren ...
p                      " einfügen

Vier Tasten zum Markieren der ganzen Funktion, ohne mit Visual-Block oder Zeilennummern zu hantieren.

Workflow 3: Klammer-Block reformatieren

text Workflow 3
" Cursor auf der öffnenden { eines Code-Blocks
v%                     " visual bis zur passenden }
=                      " auto-indent — Vim formatiert den Block neu

" oder als Single-Operator:
=%                     " auto-indent bis zur Match-Klammer (ohne Visual-Zwischenschritt)

=% ist eine der unterschätztesten Vim-Kombinationen — formatiert einen ganzen verschachtelten Block in zwei Tasten.

Interessantes

Satz-Grenzen werden über Punctuation erkannt

Vims Definition: ein Satz endet an ., ! oder ?, gefolgt von einem oder mehreren Leerzeichen, einem Tab oder Zeilenende. Zwei Punkte hintereinander („…") oder ein Punkt direkt vor einem Wort (Abkürzung wie „z.B.") werden teilweise als Satz-Grenze erkannt. Die Option cpoptions (J-Flag) ändert das Verhalten leicht.

Absatz-Grenzen sind robuster als Satz-Grenzen

&#123;/&#125; arbeiten ausschließlich an Leerzeilen — eindeutig, ohne Punctuation-Heuristik. Das macht sie sehr zuverlässig, egal welche Sprache oder welcher Filetype. In Markdown, YAML, structured Plain-Text und sogar in vielen Code-Files (Leerzeilen zwischen Funktionen) sind sie die robusteste strukturelle Navigation.

`]]` braucht öffnende Klammer in Spalte 1

Vims Default für die Top-Level-Section-Motion ist eine geschweifte Klammer in der ersten Spalte. Moderne C/Java/Go-Stile, die function foo() &#123; mit dem &#123; am Ende der Signatur schreiben, brechen diese Heuristik. Für solche Stile sind ]m/[m die zuverlässigeren Alternativen.

`%` mit matchit-Plugin lernt sprach-spezifische Paare

Ohne matchit (in modernen Vim-Versionen Default-aktiv) erkennt % nur die Standard-Paare ()/[]/&#123;&#125;. Mit matchit zusätzlich HTML-Tags, if/endif, do/end, &lt;script&gt;/&lt;/script&gt; und viele weitere. Wer prüfen will, ob matchit aktiv ist: :packadd matchit oder im neuesten Vim einfach % auf einer HTML-Tag-Klammer testen.

Counts auf semantische Motions

5} springt fünf Absätze, 3]m zur drittfolgenden Methode, 2[[ zwei Top-Level-Sections zurück. Counts auf semantischen Motions sind im Alltag sehr nützlich — sie erlauben Sprünge, die mit Zeichen- oder Wort-Motions umständlich wären.

Tree-sitter-Motions (in Neovim) sind die moderne Variante

Neovim mit nvim-treesitter-textobjects hat sprach-bewusste Funktions-, Klassen-, Argument- und Parameter-Motions, die in allen unterstützten Sprachen sauber funktionieren. In reinem Vim 9 sind Plugin-Lösungen wie vim-textobj-function oder coc-Funcobj-Mappings der Pfad — weniger universell, aber für die wichtigsten Sprachen ausreichend.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Navigation

Zur Übersicht