Über Zeichen, Wörter und Zeilen hinaus bietet Emacs Navigation in semantischen Einheiten: Sätzen, Absätzen und Funktionen. Diese Sprünge sind im Alltag oft schneller als reines Scrollen oder zeilenweises Hangeln — und sie arbeiten Mode-bewusst: in Code-Modes springst du von Funktion zu Funktion, in Text-Modes von Absatz zu Absatz, in Prosa-Modes von Satz zu Satz. Die Tasten bleiben gleich, das Verständnis dessen, was als „Einheit" gilt, liefert der Major-Mode. Wer einmal in dieser Sprache navigiert, will nicht zurück zu reinem C-n/C-p.
Satzweise mit M-a und M-e
Die kleinste semantische Einheit oberhalb des Wortes ist der Satz. Emacs bewegt Point vorwärts oder rückwärts zum nächsten Satz-Ende bzw. Satz-Anfang — schneller, als Zeile für Zeile zu lesen, und präziser als ein grobes M-x next-line-Sprung.
- M-a —
backward-sentence— springt zum Anfang des aktuellen oder vorherigen Satzes. - M-e —
forward-sentence— springt ans Ende des aktuellen oder nächsten Satzes.
Auch als M-x forward-sentence bzw. M-x backward-sentence erreichbar — praktisch, wenn die Tastenkombi auf deiner Plattform belegt ist.
Was Emacs als „Satz" versteht
Per Default endet ein Satz, wo ein ., ? oder ! steht, optional gefolgt von schließenden Klammern oder Anführungszeichen, und dann zwei Leerzeichen oder ein Zeilenende. Diese Regel stammt aus US-amerikanischer Schreibmaschinen-Typografie (zwei Leerzeichen nach jedem Punkt). Deutsche Texte folgen dieser Konvention seit Jahrzehnten nicht mehr — wir setzen ein Leerzeichen. Folge: Mit Default-Einstellung springt M-e in einem deutschen Text oft über mehrere Sätze hinweg, weil der „Doppel-Whitespace-Marker" einfach fehlt.
Die Variable, die das steuert, heißt sentence-end-double-space (Default t). Für deutsche Texte gehört sie auf nil:
;; Deutsche Texte: ein Leerzeichen nach Satzende reicht.
;; Default ist t (zwei Leerzeichen, US-Konvention).
(setq sentence-end-double-space nil)Wo dieser Code hingehört
Das Snippet kommt in deine zentrale Konfigurations-Datei ~/.emacs.d/init.el (oder ~/.config/emacs/init.el). Nach dem Eintragen entweder Emacs neu starten oder die Zeile markieren und mit M-x eval-region sofort aktivieren. Vollständige Lade-Reihenfolge und Struktur erklärt der Artikel zur Konfiguration mit init.el und early-init.el.
Verwandt und im Alltag häufig: M-k (kill-sentence) löscht vom Point bis zum Satz-Ende, C-x DEL (backward-kill-sentence) löscht rückwärts bis zum Satz-Anfang.
Absatzweise mit M-{ und M-}
Eine Ebene über dem Satz steht der Absatz. Für Texte sind Absätze die natürlichen „Kapitel-Einheiten" eines Buffers; für Code dienen sie als gröbere Blöcke zwischen Leerzeilen.
- M-{ —
backward-paragraph— zum Anfang des aktuellen oder vorherigen Absatzes. - M-} —
forward-paragraph— ans Ende des aktuellen oder nächsten Absatzes.
Alternativ als M-x forward-paragraph / M-x backward-paragraph.
Was Emacs als „Absatz" versteht
Per Default ist ein Absatz eine Folge nicht-leerer Zeilen, umrahmt von Leerzeilen (oder Buffer-Grenzen). Zwei Variablen kontrollieren das pro Major-Mode:
paragraph-start— Regex, der mögliche Absatz-Anfangszeilen matcht (typischerweise Leerzeilen oder z. B. Markdown-Headings).paragraph-separate— Regex, der Zeilen matcht, die ausschließlich als Trenner gelten und nie Teil eines Absatzes sind.
Die meisten Modes setzen diese Variablen sinnvoll: text-mode nutzt Leerzeilen, org-mode zusätzlich Headlines und Listen-Anfänge, latex-mode erkennt \par, und Programmier-Modes betrachten typischerweise Leerzeilen zwischen Code-Blöcken als Absatz-Grenzen.
DE-Tastatur-Stolperfalle
Auf deutschen Tastaturen liegen { und } auf AltGr+7 bzw. AltGr+0. AltGr ist auf den meisten Systemen intern äquivalent zu C-M- — was bedeutet, dass die Tastenkombination M-{ praktisch unerreichbar ist: man müsste M- und AltGr+7 gleichzeitig drücken, was viele Keyboard-Controller gar nicht sauber an Emacs weiterleiten.
Zwei praktikable Auswege:
- Eigene Bindings, z. B. auf M-p / M-n — Details in Sektion 07.
- Immer
M-xnutzen: M-x forward-paragraph tippen — mit Completion reichen meistM-x for-pa RET.
Funktionsweise mit C-M-a und C-M-e
Die wichtigste Einheit beim Code-Lesen ist die Funktion (in Emacs-Terminologie: defun, „definition of function"). Statt mühsam zu scrollen oder per Suche nach def/function/fn zu fahnden, springst du in einem Schritt zum Anfang oder Ende der nächsten Funktion.
- C-M-a —
beginning-of-defun— zum Anfang der aktuellen oder vorherigen Funktion. - C-M-e —
end-of-defun— ans Ende der aktuellen oder nächsten Funktion.
Auch erreichbar als M-x beginning-of-defun und M-x end-of-defun.
Was als „defun" gilt
In Emacs Lisp ist eine defun jede Top-Level-Form, also alles, was in der Spalte 0 mit ( beginnt — (defun ...), (defvar ...), (use-package ...). In anderen Sprachen liefern die Major-Modes ihre eigene Definition:
python-modeverstehtdefundclassals defun-Grenzen.c-modeundc++-modeverstehen Funktions-Definitionen samt Rückgabetyp und geschweiften Klammern.js-modeundtypescript-modeerkennenfunction-Deklarationen, Arrow-Functions und Methoden-Definitionen in Klassen.go-modespringt zwischenfunc-Definitionen.
Steuern lässt sich das pro Mode über die Variable beginning-of-defun-function (und end-of-defun-function). Modes setzen diese Hooks auf eine Funktion, die die sprach-typische Definition versteht. Für Tree-sitter-basierte Modes existiert zusätzlich treesit-defun-tactic — auf top-level gestellt, springen die Befehle zur äußersten Definition statt zur innersten, was bei verschachtelten Funktionen den Unterschied macht.
Mit Präfix-Argument weiter springen
Wie fast alle Bewegungs-Befehle in Emacs akzeptieren beginning-of-defun und end-of-defun ein Präfix-Argument. C-u 3 C-M-a springt drei Funktionen rückwärts, C-u 5 C-M-e fünf vorwärts. Negative Argumente kehren die Richtung um — C-u -2 C-M-a ist äquivalent zu „zwei Funktionen vorwärts an den Anfang".
Funktion und Absatz markieren mit C-M-h und M-h
Zu jedem Bewegungs-Befehl gibt es in Emacs einen passenden Mark-Befehl, der die entsprechende Einheit als Region setzt — ohne dass du Anfang und Ende manuell antippen müsstest. Drei Befehle gehören in diese Familie:
| Tastenkombi | Befehl | Wirkung |
|---|---|---|
C-M-h | mark-defun | aktuelle Funktion / Top-Level-Definition als Region markieren |
M-h | mark-paragraph | aktuellen Absatz als Region markieren |
C-x h | mark-whole-buffer | gesamten Buffer als Region markieren |
In Worten: C-M-h setzt den Mark an den Funktions-Anfang und Point ans Funktions-Ende — die ganze Funktion ist nun aktive Region. Daraus ergibt sich der wohl häufigste Workflow überhaupt:
- C-M-h M-w kopiert die aktuelle Funktion in den Kill-Ring.
- C-M-h C-w schneidet sie aus.
- C-M-h M-; kommentiert sie en bloc (Major-Mode-Kommentar-Syntax).
- C-M-h C-M-\ rückt sie nach den Regeln des Modes neu ein.
Die Konzepte hinter Point, Mark und Region sind im Artikel Point, Mark und Region ausführlich beschrieben — und sie greifen hier nahtlos.
Mode-Abhängigkeit semantischer Navigation
Der entscheidende Reiz dieser Befehle: die Tasten bleiben gleich, die Bedeutung passt sich an. Was als Satz, Absatz oder Funktion gilt, liefert der Major-Mode — du musst dich nicht umgewöhnen, wenn du von einem Buffer zum nächsten wechselst.
| Befehl | In text-mode / markdown-mode | In org-mode | In Programmier-Modes (python-mode, c-mode, js-mode …) |
|---|---|---|---|
forward-sentence | Punkt/Frage/Ausruf + Whitespace | dasselbe, plus Heading-Grenzen | nutzt Default-Regex — in Code-Buffern meist Kommentar-Sätze |
forward-paragraph | Leerzeilen-getrennte Blöcke | zusätzlich Headlines, Listen, Blöcke | Leerzeilen zwischen Code-Blöcken |
beginning-of-defun | selten relevant (keine Funktion) | Headlines fungieren als Top-Level-Einheiten | sprach-spezifisch: def/function/(defun …) etc. |
Praktische Folge: dieselbe Tastenkombi C-M-a bringt dich in einer Python-Datei zur vorherigen Methode, in einer Elisp-Datei zur vorherigen defun, in einer C-Datei zur vorherigen Funktion. Du lernst die Geste einmal und nutzt sie überall.
Praktische Workflows
Theorie sitzt — vier konkrete Abläufe, die diese Befehle im Alltag zur zweiten Natur machen:
„Über einen Block-Kommentar zur nächsten Funktion"
Wenn vor einer Funktion ein langer Doc-Kommentar steht, willst du oft direkt zum Funktions-Code, nicht zum Kommentar-Anfang:
- M-} — zum nächsten Absatz (überspringt den Kommentar-Block).
- C-M-a — falls Point hinter den Funktions-Anfang gerutscht ist, springt das exakt zur öffnenden Klammer / zum
def.
„Aktuellen Absatz ausschneiden"
Klassische Texte-Umstellung in zwei Tastenkombis:
- M-h — markiert den aktuellen Absatz als Region.
- C-w — schneidet ihn aus.
Danach an die neue Stelle navigieren und mit C-y einfügen. Mehrere Absätze hintereinander: M-h wiederholt erweitert die Region jeweils um den nächsten Absatz.
„Funktion duplizieren"
Eine ganze Funktion direkt unter sich nochmal kopieren — typischer Refactoring-Schritt:
- C-M-h — Funktion markieren.
- M-w — in den Kill-Ring kopieren.
- C-M-e — ans Funktions-Ende springen.
- C-y — Kopie einfügen.
„Fünf Sätze auf einmal"
Mit Präfix-Argument werden die Bewegungs-Befehle zu groben Sprung-Befehlen:
- C-u 5 M-e — fünf Sätze vorwärts.
- C-u 3 M-{ — drei Absätze zurück (sofern dein Layout
M-{zulässt). - C-u 10 C-M-a — zehn Funktionen zurück, ideal bei langen Modulen.
Alternative Bindings für DE-Tastaturen
Weil M-{ und M-} auf deutschem Layout praktisch unerreichbar sind, lohnt es sich, eigene Bindings auf gut erreichbare Tasten zu legen. Eine bewährte Wahl ist M-p / M-n:
;; Absatz-Navigation für DE-Tastatur: M-p / M-n.
;; Achtung: M-p / M-n sind in einigen Modes (Compile, IELM,
;; Comint) bereits als previous-/next-history belegt — die
;; globale Variante überschreibt nur Default-Bindings, lokale
;; Mode-Bindings bleiben erhalten.
(keymap-global-set "M-p" #'backward-paragraph)
(keymap-global-set "M-n" #'forward-paragraph)Wo dieser Code hingehört
Wie das Snippet in Sektion 01 gehört auch dieses in init.el. Wer die History-Bindings in Comint-/REPL-Buffern erhalten will, kann statt der globalen Variante eine conditionale Belegung nutzen — Detail-Pattern siehe Artikel zur Konfiguration mit init.el und early-init.el.
Wer kein eigenes Binding anlegen mag, bleibt bei M-x forward-paragraph / M-x backward-paragraph — mit Completion (fish-/vertico-artig) reichen wenige Buchstaben. Das ist langsamer als ein Chord, aber funktioniert auf jedem Layout und jeder Plattform identisch.
Interessantes
Semantische Navigation ist oft schneller als zeichen- oder zeilenweise
Über C-n durch eine 200-Zeilen-Funktion zu hangeln, ist Verschwendung — C-M-a und C-M-e springen in einem Schritt zum Anfang oder Ende. In Texten gilt dasselbe für M-}: ein Sprung statt zehn C-n.
Mode-Wechsel ändert die Bedeutung ohne Umlernen
Was als „Satz", „Absatz" oder „Funktion" gilt, liefert der Major-Mode. Dieselbe Taste C-M-a bringt dich in Python zur vorherigen Methode und in Elisp zur vorherigen defun — die Geste lernst du einmal, sie wirkt überall.
`sentence-end-double-space = nil` für deutsche Texte
Der Default t stammt aus US-Schreibmaschinen-Konventionen mit zwei Leerzeichen nach dem Punkt. Deutsche Texte nutzen ein Leerzeichen — ohne diese Anpassung springt M-e über mehrere Sätze hinweg, weil die Doppel-Whitespace-Markierung fehlt.
`M-h` und `C-M-h` sind die Mark-Pendants
Zu jeder Bewegung gibt es einen Mark-Befehl: M-h markiert den aktuellen Absatz, C-M-h die aktuelle Funktion. Aus „dahin springen" wird so „dort hingucken und arbeiten" in einer einzigen Taste.
`M-{` und `M-}` sind auf DE-Tastatur praktisch unerreichbar
Geschweifte Klammern liegen auf AltGr+7 bzw. AltGr+0; AltGr wirkt intern wie C-M-. Folge: das Chord M-{ lässt sich gar nicht sauber drücken. Lösung: eigene Bindings auf M-p / M-n oder konsequent M-x nutzen.
`beginning-of-defun` versteht jede gängige Sprache
Python, JavaScript, TypeScript, C, C++, Go, Rust, Elisp — alle Major-Modes belegen beginning-of-defun-function mit ihrer sprach-spezifischen Logik. Mode-Wechsel ändert das Verhalten transparent, ohne dass du etwas konfigurieren müsstest.
Präfix-Argument macht jeden Bewegungs-Befehl multipliziert
C-u 5 M-e = fünf Sätze vorwärts, C-u 3 C-M-a = drei Funktionen rückwärts, C-u -2 C-M-e = zwei Funktionen rückwärts ans Ende. Negative Argumente kehren die Richtung um — keine separaten Befehle nötig.
Tree-sitter-Modes können verschachtelte defuns anders behandeln
In Tree-sitter-basierten Modes steuert treesit-defun-tactic, ob die Navigation die innerste oder die äußerste Definition trifft. Setzt man die Variable auf top-level, springt C-M-a über innere Helper-Funktionen hinweg direkt zur umschließenden Funktion.
Weiterführende Ressourcen
Externe Quellen
- GNU Emacs Manual — Sentences —
M-a,M-e,M-k,C-x DELsowiesentence-endundsentence-end-double-space. - GNU Emacs Manual — Paragraphs —
M-{,M-},M-h,kill-paragraphund die Variablenparagraph-start/paragraph-separate. - GNU Emacs Manual — Moving by Defuns —
C-M-a,C-M-e,C-M-hund die Mode-Hooksbeginning-of-defun-function/end-of-defun-function. - GNU Emacs Manual — Mark — Kontext zu
mark-paragraph,mark-defunund zur Region-Logik.