Versehentlich C-x 1 gedrückt und das sorgsam aufgebaute Drei-Fenster-Layout ist weg? Mit C-x o bei vier offenen Splits durch alle Windows durchcyclen, bis endlich das richtige aktiv ist? Beide Probleme löst Emacs mit zwei Built-ins, die in den meisten Default-Konfigurationen ausgeschaltet schlummern: winner-mode für eine Layout-Historie mit Undo/Redo und windmove für direktionale Navigation per Shift+Pfeil. Wer mehr als vier Splits gleichzeitig hat, ergänzt beides um ace-window — ein externes Paket, das in jedes Window einen Sprungbuchstaben einblendet und damit konstant schnell bleibt, egal wie viele Fenster offen sind.

winner-mode — Layout-Undo und -Redo

winner-mode ist ein globaler Minor-Mode, der jede Änderung der Window-Konfiguration in einem Ring speichert — pro Frame eine eigene Historie. Wer also fünf Splits aufbaut, einen schließt, einen neuen öffnet und am Ende reflexhaft C-x 1 drückt, verliert nichts: C-c left rollt den Ring schrittweise zurück, C-c right wieder vorwärts.

C-c <left> C-c <right>

Die zugehörigen Befehle heißen winner-undo und winner-redo. Wichtig zu verstehen: rückgängig gemacht wird nicht der Buffer-Inhalt, sondern ausschließlich die Anordnung der Windows — welche Splits existieren, wie groß sie sind und welcher Buffer in welchem Window sichtbar ist. Textänderungen bleiben unangetastet und kennen ihr eigenes Undo per C-/.

Ein typisches Szenario: drei vertikale Splits mit Code, Test und Doku. Ein neuer Hilfe-Buffer öffnet sich als viertes Window und schiebt das Layout durcheinander. Statt jetzt mühsam neu zu splitten — einfach C-c left, das Layout vor dem Hilfe-Aufruf ist zurück.

Aktiviert wird der Mode mit einer einzigen Zeile:

elisp init.el — winner-mode aktivieren
;; Window-Layout-Historie aktivieren
(winner-mode 1)

Wo dieser Code hingehört: in ~/.emacs.d/init.el (bzw. ~/.config/emacs/init.el seit Emacs 27). Details zur Init-Datei und ihrer Ladereihenfolge stehen im Artikel zu init.el und early-init.el.

winner-mode-Eigenheiten und Tuning

Der Mode ist absichtlich genügsam konfigurierbar — drei Variablen reichen für fast alle Bedürfnisse:

VariableWirkung
winner-dont-bind-my-keyswenn t, lässt winner-mode die Default-Bindings C-c left/C-c right in Ruhe — du belegst sie selbst
winner-ring-sizemaximale Anzahl gespeicherter Konfigurationen pro Frame (Default 200) — selten ein Problem
winner-boring-buffersListe von Buffer-Namen, deren Auftauchen die Historie nicht „interessant" macht — z. B. *Completions*

Die boring-buffers-Liste ist subtiler, als sie wirkt: standardmäßig kennt winner-mode bereits ein paar kurzlebige Buffer (Completions, einige Hilfe-Varianten) und „springt darüber hinweg". Erweitert man die Liste, ignoriert winner-undo weitere Layouts, in denen nur dieser eine störende Buffer aufgetaucht ist — sehr nützlich, wenn man *Backtrace* oder ähnliches nicht in der Historie sehen will.

Zwei Verhaltens-Punkte, die in der Praxis auftauchen:

  • Pro Frame eine Historie. Wer mit mehreren Frames arbeitet, hat in jedem davon eine eigene Undo-Liste — winner-undo im linken Frame beeinflusst das Layout im rechten nicht.
  • Zusammenspiel mit tab-bar-mode. Wechsel zwischen Tabs taucht in der Winner-Historie nicht auf — jeder Tab hält seine eigene Window-Konfiguration ohnehin separat. Innerhalb eines Tabs funktioniert Winner aber wie gewohnt.

Wer die Default-Bindings umlegen will, weil C-c left/C-c right in einem Mode kollidieren (Org-Mode etwa nutzt sie nicht, aber manche Sprach-Modes schon), setzt winner-dont-bind-my-keys vor dem Aktivieren und bindet manuell:

elisp init.el — eigene winner-Bindings
(setq winner-dont-bind-my-keys t)
(winner-mode 1)
(keymap-global-set "C-c w u" #'winner-undo)
(keymap-global-set "C-c w r" #'winner-redo)

windmove — direktionale Window-Navigation

Vanilla-Emacs kennt für den Window-Wechsel nur C-x o (other-window) — und das cyclet stur in einer festen Reihenfolge weiter. Bei zwei Windows ist das egal, bei vier wird es bereits zur Lotterie: man drückt, schaut, drückt nochmal. windmove ersetzt diese Cycling-Logik durch echte Richtungs-Sprünge:

S-<left> S-<right> S-<up> S-<down>

Die zugehörigen Befehle heißen windmove-left, windmove-right, windmove-up und windmove-down. Sie nehmen die aktuelle Window-Position als Bezugspunkt und springen direkt in den Nachbarn der gewünschten Richtung — egal ob das Layout aus drei oder zehn Splits besteht.

Aktivierung der Defaults in einer Zeile:

elisp init.el — windmove-Bindings setzen
;; Shift+Pfeil springt in die entsprechende Richtung
(windmove-default-keybindings)

Ein bekannter Konflikt: Vanilla-Emacs nutzt Shift+Pfeil normalerweise für Shift-Selection (Text mit Cursor markieren wie in jedem GUI-Editor). windmove-default-keybindings überschreibt diese Bindings — Shift-Selection muss dann über C-SPC (set-mark-command) und normale Cursor-Tasten erledigt werden. Wer Shift-Selection nicht aufgeben will, übergibt einen alternativen Modifier:

elisp init.el — windmove mit Meta statt Shift
;; M-S-Pfeil statt S-Pfeil — Shift-Selection bleibt erhalten
(windmove-default-keybindings 'meta)

Auf macOS und unter manchen Linux-DEs kollidieren S-left/S-right im Terminal-Emacs mit Tab-Wechsel des Terminals — dort hilft entweder der Meta-Modifier oder ein Prefix-Setup nach dem spacemacs-Vorbild mit M-o als Dispatcher.

windmove erweitert — Swap und Display-Direction

Seit Emacs 27 bringt windmove drei weitere Bindings-Helfer mit, die im Alltag oft unterschätzt werden:

FunktionWirkung
windmove-swap-states-default-keybindingsbindet windmove-swap-states-left/right/up/down — tauscht die Buffer zweier Nachbar-Windows
windmove-display-default-keybindingsbindet windmove-display-left/right/up/down — der nächste gewählte Buffer erscheint im Window in der gegebenen Richtung
windmove-delete-default-keybindingsbindet windmove-delete-left/right/up/down — schließt das Nachbar-Window in der Richtung

Besonders nützlich ist swap-states: man steht im Code-Window, rechts daneben liegt der Test — C-S-right und beide Buffer haben die Plätze getauscht, ohne dass auch nur ein Split neu erzeugt wurde. Genau das wollte man in den meisten Fällen, in denen man früher C-x b + Re-Open in Kombination geübt hat.

Ein typisches Setup, das alle drei Helfer mit einem eigenen Modifier-Prefix kombiniert:

elisp init.el — windmove mit Swap und Display
;; Navigation auf Shift+Pfeil
(windmove-default-keybindings)
;; Buffer-Tausch auf C-S-Pfeil
(windmove-swap-states-default-keybindings "C-S-")
;; "nächsten Buffer in Richtung" auf C-M-S-Pfeil
(windmove-display-default-keybindings "C-M-S-")

Das display--Set ist der Geheimtipp: einmal C-M-S-right gedrückt, danach C-x b foo RET — der Buffer foo öffnet sich automatisch im rechten Nachbarn, statt das aktuelle Window zu übernehmen. Für Vergleichs-Sessions („Code links, gleich daneben die Doku") spart das viele Handgriffe.

ace-window — Buchstaben-Overlay-Navigation

ace-window (von Oleh Krehel, dem Autor von avy) ist kein Built-in, aber in praktisch jeder modernen Emacs-Distribution vorinstalliert und über MELPA in zwei Klicks nachgeladen. Das Konzept ist anders als bei windmove: statt direktional zu springen, blendet ace-window beim Aufruf in jedem Window einen großen Buchstaben ein — drückt man den Buchstaben, ist man dort.

M-o

Der Vorteil zeigt sich bei vielen Splits: egal ob drei, sechs oder zehn Windows offen sind — der Aufwand bleibt konstant zwei Tasten (M-o plus Buchstabe). windmove braucht bei zehn Windows im Worst-Case mehrere Pfeil-Drücke; other-window cyclet im schlimmsten Fall neunmal. Eine typische Konfiguration mit use-package:

elisp init.el — ace-window einrichten
(use-package ace-window
  :ensure t
  :bind ("M-o" . ace-window)
  :custom
  (aw-keys '(?a ?s ?d ?f ?j ?k ?l))
  (aw-dispatch-always t))

Wo dieser Code hingehört: in deine init.el. Voraussetzung ist ein eingerichtetes Paket-Archiv (MELPA) — Details dazu im Artikel zu init.el und early-init.el.

Die aw-keys-Liste legt die Buchstaben fest, mit denen die Windows beschriftet werden — Home-Row ist hier deutlich angenehmer als die Default-Zahlen 1-9. aw-dispatch-always aktiviert das Dispatch-Menü auch dann, wenn nur ein Window sichtbar ist, sodass man unterwegs ohne Re-Start zu Sub-Aktionen wechseln kann.

Diese Sub-Aktionen sind der zweite, oft übersehene Mehrwert. Nach M-o lässt sich statt eines Buchstabens auch eine Aktion drücken:

TasteAktion
xWindow unter dem nachfolgend gewählten Buchstaben schließen
mBuffer-Inhalte zweier Windows tauschen
Maktuelles Window an die Stelle des gewählten verschieben
cBuffer in das gewählte Window kopieren
jim gewählten Window den Buffer wechseln
v / bWindow vertikal/horizontal teilen
oaktuelles Window maximieren (alle anderen schließen)

Damit deckt ace-window viele Operationen ab, für die man sonst C-x 1, C-x 0 oder C-x b separat braucht — alles aus einem Prefix heraus.

Wann winner, windmove, ace? — die Entscheidungshilfe

Die drei Werkzeuge schließen sich nicht aus, ergänzen sich aber je nach Layout-Anzahl unterschiedlich gut:

SituationEmpfehlung
1-2 SplitsC-x o reicht — kein Tooling nötig
3-4 Splitswindmove (direkter Richtungs-Sprung statt Cycling)
5+ Splits, oder viele kleine Hilfe-Windowsace-window (konstanter Aufwand, plus Dispatch-Aktionen)
häufige Layout-Experimente, C-x 1-Reflexwinner-mode immer aktiv lassen — Layout-Undo ist die einzige Versicherung
typisches Tagesgeschäftwinner-mode + windmove als Basis, ace-window ergänzend für Power-Momente

Praktische Empfehlung: winner-mode und windmove gehören in jede init.el ab dem ersten Tag. Beide sind Built-in, beide kosten kein Performance-Budget, beide brauchen keinen Paket-Manager. ace-window lohnt sich, sobald man regelmäßig mit mehr als vier sichtbaren Windows arbeitet — vorher ist der zweite Tastendruck (Buchstabe) noch keine Ersparnis gegenüber dem ersten (Pfeil).

Mini-Setup für den ersten Tag

Wer den Artikel überfliegt und nur drei Zeilen mitnehmen will: dieser Block reicht für einen sofortigen Komfortgewinn — alle Pakete Built-in, kein Tap, kein Repo, keine Lizenzfrage.

elisp init.el — Window-Komfort an einem Stück
;; Window-Komfort — direkt aktivieren
(winner-mode 1)
(windmove-default-keybindings)

;; Optional: Buffer-Swap mit C-S-Pfeil
(windmove-swap-states-default-keybindings "C-S-")

Direkt in ~/.emacs.d/init.el (oder ~/.config/emacs/init.el) einfügen, Emacs neu starten oder M-x eval-buffer über die Init-Datei laufen lassen — sofort steht die Layout-Historie auf C-c left/C-c right, die direktionale Navigation auf S-Pfeil und der Buffer-Tausch auf C-S-Pfeil. Konfigurations-Grundlagen rund um Init-Dateien stehen im Artikel zu init.el und early-init.el. ace-window als externes Paket folgt einen Schritt später, sobald Paket-Management eingerichtet ist.

Besonderheiten

winner-mode ist Built-in seit den späten 90ern – aber per Default aus

winner.el hat Per Abrahamsen 1997 geschrieben, sie ist seit Emacs 20 fester Bestandteil der Distribution — aber im Default-Build nicht aktiv. Das Aktivieren mit (winner-mode 1) gehört zu den lohnendsten Tweaks überhaupt, weil es kostet nichts und schützt vor jedem versehentlichen C-x 1.

windmove rechnet die Richtung relativ zum aktiven Window

Egal wie komplex das Layout ist — windmove-right springt in das nächstgelegene Window, dessen linker Rand rechts vom aktiven Window liegt und das vertikal überlappt. Diagonale Sprünge gibt es bewusst nicht; das Verhalten ist deterministisch und gut vorhersagbar.

`windmove-swap-states-*` tauscht Buffer, ohne Splits anzurühren

Statt einen Buffer wegzukillen und neu zu öffnen, vertauscht windmove-swap-states-right einfach die Inhalte zweier Nachbar-Windows. Das Layout bleibt identisch, nur die Buffer wandern eine Position weiter — perfekt für „ich will den Test rechts statt links sehen".

ace-window ergänzt windmove, statt es zu ersetzen

Beide Pakete arbeiten konfliktfrei parallel. Faustregel: bis vier Windows reicht windmove schneller (eine Taste), ab fünf wird ace-window schneller (zwei Tasten konstant statt mehrere Pfeile). Profis haben beides aktiv und greifen je nach Layout-Größe spontan.

winner-mode und tab-bar-mode arbeiten getrennt voneinander

Die Layout-Historie ist pro Frame organisiert, nicht pro Tab. Beim Tab-Wechsel via tab-bar-mode lädt Emacs die komplette Window-Konfiguration des Ziel-Tabs neu — winner-undo arbeitet danach innerhalb dieses Tabs weiter, ohne die Historie des anderen zu sehen.

Shift+Pfeil kollidiert mit Shift-Selection – bewusste Entscheidung

windmove-default-keybindings deaktiviert Shift-Selection für die vier Pfeile. Wer Shift+Pfeil zum Markieren behalten will, ruft (windmove-default-keybindings 'meta) auf und bekommt M-S-Pfeil als Window-Sprung — Shift-Selection bleibt unangetastet.

Org-Mode überschreibt Shift+Pfeil kontextabhängig – das ist okay

In Org-Buffern sind S-up/S-down an Listen-Promotion/Demotion und Datums-Inkrement gebunden, S-left/S-right an Zustands-Wechsel. windmove greift dort, wo Org selbst keine spezielle Aktion hinterlegt hat — die org-support-shift-select-Variable steuert den genauen Fall-Back. Konflikte sind in der Praxis selten.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Buffer, Fenster & Frames

Zur Übersicht