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

elisp init.el — Satz-Ende deutsch konfigurieren
;; 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-x nutzen: M-x forward-paragraph tippen — mit Completion reichen meist M-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-mode versteht def und class als defun-Grenzen.
  • c-mode und c++-mode verstehen Funktions-Definitionen samt Rückgabetyp und geschweiften Klammern.
  • js-mode und typescript-mode erkennen function-Deklarationen, Arrow-Functions und Methoden-Definitionen in Klassen.
  • go-mode springt zwischen func-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:

TastenkombiBefehlWirkung
C-M-hmark-defunaktuelle Funktion / Top-Level-Definition als Region markieren
M-hmark-paragraphaktuellen Absatz als Region markieren
C-x hmark-whole-buffergesamten 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.

BefehlIn text-mode / markdown-modeIn org-modeIn Programmier-Modes (python-mode, c-mode, js-mode …)
forward-sentencePunkt/Frage/Ausruf + Whitespacedasselbe, plus Heading-Grenzennutzt Default-Regex — in Code-Buffern meist Kommentar-Sätze
forward-paragraphLeerzeilen-getrennte Blöckezusätzlich Headlines, Listen, BlöckeLeerzeilen zwischen Code-Blöcken
beginning-of-defunselten relevant (keine Funktion)Headlines fungieren als Top-Level-Einheitensprach-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:

  1. M-} — zum nächsten Absatz (überspringt den Kommentar-Block).
  2. 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:

  1. M-h — markiert den aktuellen Absatz als Region.
  2. 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:

  1. C-M-h — Funktion markieren.
  2. M-w — in den Kill-Ring kopieren.
  3. C-M-e — ans Funktions-Ende springen.
  4. 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:

elisp init.el — Absatz-Navigation auf DE-freundliche Tasten
;; 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

Verwandte Artikel

/ Weiter

Zurück zu Navigation

Zur Übersicht