Vim unterscheidet zwischen zwei Wort-Begriffen, und beide haben eigene Motions: das kleine Wort (word) ist eine Sequenz von Buchstaben, Ziffern und Unterstrich, und endet an jedem Punctuation-Zeichen. Das große WORD ist eine Sequenz beliebiger Nicht-Whitespace-Zeichen und endet erst am nächsten Leerzeichen oder Zeilenende. Die Konvention ist über die ganze Vim-Bedienung konsistent: Kleinbuchstabe = enge Definition, Großbuchstabe = weite Definition. Bei foo.bar.baz springt w zwischen foo, ., bar, ., baz (fünf Wörter), W springt direkt zum nächsten Whitespace (ein WORD). Dieser Artikel deckt beide Familien ab — w/b/e/ge und ihre Großbuchstaben-Pendants —, zeigt, wie die iskeyword-Option den Wort-Begriff pro Dateityp anpasst, und gibt typische Operator-Kombinationen.
Wort vs. WORD: die zwei Definitionen
Vim hat zwei distinkte Begriffe für „Wort":
| Begriff | Definition | Beispiel-Grenzen in foo.bar |
|---|---|---|
| word | Sequenz von iskeyword-Zeichen (Default: Buchstaben, Ziffern, _) | foo, ., bar — drei Wörter |
| WORD | Sequenz beliebiger Nicht-Whitespace-Zeichen | foo.bar — ein WORD |
Der praktische Unterschied wird sofort sichtbar an Zeilen mit Punctuation. Wichtig: ohne Punctuation verhalten sich w und W identisch — der Unterschied wird erst durch Zeichen wie ., ,, ;, /, =, (, " erkennbar.
Ein bewusst minimales Test-Beispiel:
Buffer: foo.bar.baz qux
^
Mit Cursor am Anfang (Spalte 1), drücke nacheinander:
w → Cursor auf "." (Spalte 4 — der erste Punkt ist ein eigenes Wort)
w → Cursor auf "bar" (Spalte 5)
w → Cursor auf "." (Spalte 8)
w → Cursor auf "baz" (Spalte 9)
w → Cursor auf "qux" (Spalte 13)
Mit Cursor zurück am Anfang (Taste 0), drücke:
W → Cursor direkt auf "qux" (Spalte 13) — EIN Sprung
Grund: "foo.bar.baz" ist EIN WORD, da kein Whitespace dazwischen.Fünf word-Sprünge mit w gegenüber einem einzigen WORD-Sprung mit W — dasselbe Ziel, zwei sehr verschiedene Definitionen von „Wort".
Mit w springt der Cursor durch jeden Punctuation-Übergang. Mit W überspringt er sie als Teil eines zusammenhängenden „Worts ohne Whitespace". Beide haben ihre Anwendung — w für präzise Code-Edits innerhalb eines Ausdrucks, W für das schnelle Überqueren ganzer Tokens.
Wer in einer Zeile wie hello world foo bar testet, sieht keinen Unterschied: hier sind alle Wörter sowohl word als auch WORD, weil keine Punctuation vorkommt. Der Test braucht zwingend Sonderzeichen innerhalb der Wörter, damit der Unterschied sichtbar wird.
Die acht Wort-Motions im Überblick
Beide Wort-Begriffe haben jeweils vier Motions — vorwärts und rückwärts, jeweils zum Anfang oder Ende:
| word (klein) | WORD (groß) | Bewegung |
|---|---|---|
w | W | zum Anfang des nächsten Worts |
b | B | zum Anfang des vorherigen Worts |
e | E | zum Ende des nächsten Worts |
ge | gE | zum Ende des vorherigen Worts |
Die Mnemoniken:
- w = word — vorwärts zum nächsten Wort-Anfang
- b = back — zurück zum vorherigen Wort-Anfang
- e = end — vorwärts zum nächsten Wort-Ende
- ge = go-end-back — zurück zum vorherigen Wort-Ende
Die Großbuchstaben-Varianten machen exakt dasselbe, nur mit WORD-Definition.
Zeile: foo.bar baz, qux
↑
w → "." (Anfang des nächsten Worts — "." ist auch ein Wort)
W → "baz" (Anfang des nächsten WORDs)
e → "o" in foo (Ende des aktuellen Worts)
E → "r" in bar (Ende des aktuellen WORDs)
Cursor am Zeilenende:
b → "q" in qux (Anfang des aktuellen/vorherigen Worts)
B → "q" in qux (gleich, weil "qux" auch ein WORD ist)
ge → letztes "z" (Ende des vorherigen Worts)
gE → letztes "z" (Ende des vorherigen WORDs)In der Praxis sind w, b, e die häufigsten — ge und die Großbuchstaben-Varianten kommen seltener vor, sind aber genau dann nützlich, wenn man sie braucht.
Wort-Motions mit Operatoren
Wort-Motions kombinieren sich mit jedem Operator zu sehr alltäglichen Edit-Befehlen:
| Befehl | Aktion |
|---|---|
dw | lösche bis zum nächsten Wort-Anfang (häufigste Operator-Motion) |
de | lösche bis zum Wort-Ende — lässt den Whitespace dahinter stehen |
cw | ändere bis zum Wort-Anfang (= Wort weg, Insert) |
ciw | ändere das innere Wort (Text-Object — siehe Kapitel 8) |
yw | kopiere bis zum Wort-Anfang |
yiw | kopiere das ganze Wort unter Cursor |
gUw | uppercase bis zum Wort-Anfang |
>aw | rücke das „around word" ein |
Ein subtiler, aber wichtiger Punkt: dw vs. de vs. diw.
Zeile: foo bar baz
↑ (Cursor am f von foo)
dw → "bar baz" (löscht "foo" PLUS die zwei Leerzeichen)
de → " bar baz" (löscht nur "foo", Whitespace bleibt)
diw → " bar baz" (löscht das innere Wort — wie de von hier aus)
Zeile: foo bar baz
↑ (Cursor am b von bar — mitten in der Zeile)
dw → "foo baz" (löscht "bar " — ein Wort PLUS Whitespace)
de → "foo baz" (löscht "bar", Whitespace bleibt)
diw → "foo baz" (löscht "bar", Cursor egal innerhalb)diw ist die positionsunabhängige Variante — egal wo der Cursor innerhalb des Worts steht. dw ist positions-sensitiv und nimmt den nachfolgenden Whitespace mit. de ist positions-sensitiv ohne Whitespace.
Im Alltag ist diw die häufigste Wahl für „dieses Wort weg" — der Cursor muss nicht am Wort-Anfang stehen, der Edit ist immer derselbe.
Counts mit Wort-Motions
Counts multiplizieren auch hier:
3w " drei Wörter vorwärts
5b " fünf Wörter rückwärts
2e " bis zum Ende des übernächsten Worts
4W " vier WORDs vorwärts
" Mit Operatoren — multiplikativ:
d3w " lösche drei Wörter (= dw . . )
c2W " ändere zwei WORDs
y5b " kopiere fünf Wörter rückwärtsd3w ist eine sehr gängige Massen-Lösch-Operation: drei Wörter weg, in vier Tasten. Die alternative Notation 3dw ist funktional identisch (siehe Count-Präfixe).
iskeyword — den Wort-Begriff konfigurieren
Vims Definition von „word" basiert auf der Option iskeyword — einer Liste von Zeichen, die als Teil eines Worts gelten. Default in den meisten Filetypes:
:set iskeyword?iskeyword=@,48-57,_,192-255Die kryptische Notation bedeutet:
@— alle alphabetischen Zeichen (entsprechendisalpha()der C-Lib)48-57— die ASCII-Range für Ziffern (0-9)_— der Unterstrich192-255— die ASCII-Range für UTF-8 Latin1-Buchstaben (ä, ö, ü, é, à, …)
Per Filetype kann diese Liste angepasst werden. Das ist nützlich, weil in manchen Sprachen Zeichen, die in anderen Punctuation sind, tatsächlich Teil eines Identifier sein können:
" In CSS sind Klassen-Namen wie "main-content" — der Bindestrich
" ist Teil des Identifier. Mit Default-iskeyword springt w durch
" den Bindestrich, was lästig ist beim Class-Editing.
setlocal iskeyword+=-
" Jetzt behandelt Vim "main-content" als ein einzelnes Wort.
" ciw ändert beides auf einmal." Scheme/Lisp: Identifier können Bindestriche und Fragezeichen enthalten
" z. B. "null?", "string->number"
setlocal iskeyword+=-,?,!Syntax-Spezifika: hinzufügen, entfernen, ersetzen
:set iskeyword+=- " - hinzufügen
:set iskeyword-=_ " _ entfernen (selten gewollt)
:set iskeyword=a-z,A-Z " komplett neu setzen (nur Buchstaben)
:setlocal iskeyword+=- " nur für den aktuellen BufferIn der Praxis ist setlocal mit += der häufigste Fall — buffer-spezifische Erweiterung der Default-Liste.
Wann word, wann WORD
Faustregeln aus der Praxis:
| Situation | Empfehlung |
|---|---|
Einzelnen Identifier ändern (var_name) | ciw (word) |
Kompletten Ausdruck ändern (obj.prop.field) | ciW (WORD) |
Über CamelCase springen (getFullName) | w allein behandelt es als 1 Wort — Plugin nötig für Sub-word-Sprünge |
Pfad ändern (/usr/local/bin) | ciW (WORD) |
Hex-String ändern (#ff5500) | ciW (WORD) |
| URL editieren | ciW (WORD) |
| Eine Wort-Folge im Fließtext löschen | d3w (word, mehrfach) |
| Ende einer Zeile mit Punctuation | gE für sauberen Sprung |
Für Sub-word-Navigation in CamelCase oder snake_case gibt es Plugins:
- vim-wordmotion (Sushe) — fügt zusätzliche Motions hinzu, die durch CamelCase und snake_case einzeln springen.
- vim-camelcasemotion — der Klassiker, definiert
<leader>w,<leader>b, etc. als Sub-word-Motions.
Diese ändern Vim's eingebautes w nicht, sondern liefern parallele Motions. Wer regelmäßig CamelCase editiert, hat damit einen sinnvollen Power-Up.
Praxis-Workflows
Drei typische Anwendungen:
Workflow 1: alle Vorkommen eines Identifiers ändern
" Aufgabe: alle "old_name" im Buffer durch "new_name" ersetzen, mit Kontrolle
/old_name<CR> " erste Stelle finden
ciwnew_name<Esc> " inneres Wort ändern
n. " nächste Stelle, gleicher Edit
n. " ...Das iw (inner word) ist hier exakt richtig — egal wo n den Cursor innerhalb des Worts platziert, der Edit trifft das ganze Wort.
Workflow 2: Punctuation-getrennte Werte editieren
" Buffer: let url = "https://example.com/api/v1/users";
" Aufgabe: nur "users" durch "products" ersetzen
" Cursor irgendwo am Anfang der Zeile
f" " zum ersten Anführungszeichen springen
2W " zwei WORDs vorwärts (URL ist 1 WORD; das ; danach das 2.)
b " ein Wort zurück — auf "users" (word, ohne /-Sprünge)
ciw products<Esc> " ändernHier ist die Kombination aus W (für den schnellen URL-Sprung) und w/b (für die präzise Wort-Auswahl in der URL) typisch.
Workflow 3: am Wort-Ende ein Suffix anhängen
" Buffer: console.log("test")
" Aufgabe: nach "test" ein "_v2" anhängen
" Cursor an "console" am Zeilenanfang
f" " zum ersten "
ea_v2<Esc> " e = ans Ende von "test", a = append nach Cursor, _v2 tippene plus a ist die Kombination für „direkt nach diesem Wort weiterschreiben" — vier Tasten total.
Besonderheiten
Großbuchstabe = weite Definition, durchgehend in Vim
Die kleinbuchstabe/Großbuchstabe-Konvention für „eng" und „weit" gilt nicht nur bei Wort-Motions: f/F (vorwärts/rückwärts), c/C (bis Motion/bis Zeilenende), y/Y, d/D. Wer die Logik einmal verinnerlicht hat, errät bei vielen Vim-Befehlen die Großbuchstaben-Variante korrekt.
`dw` nimmt Whitespace mit, `de` nicht
Subtiler, aber wichtiger Unterschied. dw löscht ein Wort UND die Leerzeichen dahinter — sodass die Nachbarn zusammenrücken. de löscht nur das Wort, der Whitespace bleibt. Bei mehreren dw hintereinander entstehen sauber zusammenhängende Texte, bei mehreren de bleiben Doppel-Leerzeichen.
`ciw` ist positionsunabhängig — `cw` nicht
cw ändert vom Cursor bis zum nächsten Wort-Anfang. Cursor mitten im Wort heißt: nur ein Teil wird geändert. ciw ändert das ganze umgebende Wort, egal wo der Cursor steht. Im Alltag fast immer ciw als Reflex.
iskeyword pro Filetype als verstecktes Power-Tool
Wer in CSS, Scheme, Lisp oder anderen Sprachen mit Sonder-Identifier-Zeichen arbeitet, gewinnt erheblich durch ein angepasstes iskeyword. Die Anpassung gehört in eine ftplugin/<lang>.vim-Datei, nicht in die globale .vimrc — sonst wirkt sie überall und führt zu unerwarteten Wort-Grenzen in anderen Filetypes.
`ge` ist die unauffällige Vierte
w/b/e kennt fast jeder. ge (rückwärts zum Wort-Ende) wird oft vergessen — ist aber bei „direkt nach diesem Wort weiterschreiben"-Workflows sehr nützlich. Mit gea (ge + append) springt der Cursor ans vorherige Wort-Ende und betritt Insert dahinter.
Mehrbyte-Zeichen werden korrekt behandelt
Vims Default-iskeyword umfasst die Latin1-UTF-8-Range (192-255), womit deutsche Umlaute (ä, ö, ü, ß) korrekt als Wort-Bestandteile gelten. Bei exotischeren Schriften (Kyrillisch, Griechisch, CJK) braucht es Anpassungen — meistens funktionieren die filetype-spezifischen Defaults dafür.
Weiterführende Ressourcen
Externe Quellen
- Vim Help: word-motions — vollständige Wort-Motion-Referenz.
- Vim Help: WORD — Definition von WORD.
- Vim Help: iskeyword — Konfiguration des Wort-Begriffs.
- chaoren/vim-wordmotion — Sub-word-Motions für CamelCase und snake_case.
- bkad/CamelCaseMotion — der Klassiker für CamelCase-Sprünge.