1 Punkte von GN⁺ 2024-05-13 | 1 Kommentare | Auf WhatsApp teilen
  • Das Fenstermanagement in Emacs basiert auf einer flexiblen Struktur, in der Buffer und Fenster getrennt sind, während die grundlegende Bedienung etwas grob ausfällt; Nutzer müssen daher Werkzeuge und Gewohnheiten kombinieren, um ihren eigenen Arbeitsablauf zu schaffen
  • Der Schwerpunkt des Textes liegt nicht auf display-buffer-Regeln oder tab-basierten Workspaces, sondern auf manueller Bedienung innerhalb eines einzelnen Emacs-Frames: Fokusbewegung, Buffer-Platzierung, Aufteilen und Löschen sowie temporäre Arbeiten
  • other-window, windmove, winum, ace-window, die Maus, transpose-frame, window-prefix-map, other-window-prefix und winner-mode übernehmen jeweils zyklische Navigation, richtungsbasierte Bewegung, Auswahl per Nummer, Auswahl per Hinweis, Layout-Transformation und Wiederherstellung
  • Mit ace-window und Avy kann man ein bestimmtes Fenster auswählen und danach einen Befehl ausführen oder direkt zu einer Textposition springen, um Fensterwechsel selbst zu reduzieren
  • Emacs-Fenstermanagement ist weniger ein komplexes starres System als vielmehr ein offenes Problem; display-buffer-alist, Popper·Popwin, Manipulation des Fensterbaums und die Integration mit Tiling-WMs sind zwar mächtig, bringen aber Konfigurationsaufwand und Lücken mit sich

Was mit Fenstermanagement in Emacs gemeint ist

  • Ein Fenster(window) in Emacs ist ein Viewport oder Panel innerhalb eines Frames, während ein Buffer(buffer) ein zusammenhängender Textblock ist, der Dateiinhalte enthalten kann, aber nicht muss
  • Viele IDEs und Editoren verschmelzen die Konzepte von Fenster und Buffer praktisch, um die kognitive Last zu senken; Emacs trennt beides und ermöglicht dadurch flexiblere Anordnungen
    • Dieselbe Datei zweimal anzusehen ist einfach
    • Buffer, die keiner Datei direkt entsprechen, lassen sich ebenfalls natürlich handhaben
    • Die indirect buffers von Emacs sind eher eine „Live“-Kopie des gesamten Buffers
  • Diese Trennung hat für neue Nutzer ihren Preis
    • Fenster müssen innerhalb des Frames an die gewünschte Position gebracht werden
    • Der gewünschte Buffer muss in das gewünschte Fenster gelegt werden
    • Am Anfang tritt die Bedienlast oft stärker hervor als die Vorteile der getrennten Struktur

Bereiche, die dieser Text nicht behandelt

  • Automatische Regeln zur Buffer-Anzeige, die display-buffer vollständig steuern, sind nicht das zentrale Thema
  • Tabs, Workspaces, Buffer-Isolation und Sitzungs-Persistenz liegen ebenfalls außerhalb des Kernbereichs
  • Auch radikale Alternativen, die innerhalb von Emacs wie ein eigener Fenstermanager arbeiten, bleiben außen vor
    • Edwina erzwingt ein automatisches Tiling-Layout im DWM-Stil mit Master-and-Stack
    • HyControl bietet unter anderem ein Bedienfeld für Aktionen auf Fensterlayouts und die Anzeige gleichmäßiger Grids
  • Der eigentliche Fokus liegt auf manuellen, alltäglichen Bedienvorgängen
    • Wechsel des Fensterfokus
    • Verschieben von Buffern zwischen Fenstern
    • Aufteilen und Löschen von Fenstern
    • Steuerung des Ziel-Fensters für die Anzeige während der Befehlsausführung

Grundlegende Navigation: other-window und das „nächste Fenster“

  • other-window ist der grundlegende Befehl zum Fensterwechsel, den man im Emacs-Tutorial lernt; die Standardtaste ist C-x o
  • Die Auswahlreihenfolge läuft im Frame im Allgemeinen im Uhrzeigersinn zyklisch
    • Bei wenigen Fenstern ist das simpel und gut brauchbar
    • Je mehr Fenster es gibt, desto öfter muss der Befehl aufgerufen werden, um die gewünschte Position zu erreichen
  • Es gibt auch praktische Anpassungsmöglichkeiten
    • Man kann den Befehl auf leichter erreichbare Tasten wie M-o legen
    • Mit einem numerischen Argument lässt sich mehrere Positionen überspringen oder rückwärts gehen
    • Mit aktiviertem repeat-mode sind wiederholte Eingaben wie C-x o o o... oder M-o o o... möglich
  • Wenn der Fensterparameter no-other-window gesetzt ist, überspringt other-window bestimmte Fenster
    • Deshalb fallen dateimanagerartige Seitenfenster wie dired-sidebar oder dirvish-side aus dem Zielbereich von other-window heraus
  • Das Konzept des „nächsten Fensters“ ist auch das Standardziel für Befehle, die auf andere Fenster wirken, etwa scroll-other-window

Richtungsbasierte Navigation: windmove

  • windmove ist eine eingebaute Bibliothek, die den Fensterfokus anhand einer Richtung verschiebt
    • Das kommt der von Vim-Nutzern erwarteten Navigation nach links, rechts, oben und unten nahe
    • Auch Nutzer von evil-mode verwenden intern Windmove
  • windmove-left, windmove-right, windmove-up und windmove-down lassen sich etwa auf WASD, HJKL oder die Pfeiltasten legen
  • Die Befehle windmove-swap-states-left/right/up/down tauschen die Buffer von Fenstern anhand einer Richtung aus
    • Dabei bewegt sich der Fokus zusammen mit dem Buffer
  • Mit der windmove-delete-*-Familie lassen sich auch Fenster in einer bestimmten Richtung löschen, aber der Text behandelt später noch andere Wege
  • In Tiling-WM-Umgebungen kann man die Navigation zwischen Emacs-internen Fenstern und OS-Fenstern auf dieselben Tasten legen
    • Ein Beispiel für Emacs+i3wm-Integration ist i3 integration
    • Ein Konfigurationsbeispiel für qtile findet sich in emacs-wm.el

Emacs-Fenster an das OS als Fenster übergeben

  • frames-only-mode öffnet alle Buffer nicht in Emacs-Fenstern, sondern in neuen Frames, damit sie vom Fenstermanager des Betriebssystems verwaltet werden
  • Dieser Ansatz hebt Emacs-Buffer auf dieselbe Ebene wie OS-Fenster, sodass sich beide mit denselben Tasten verwalten lassen
  • Werkzeuge wie Avy, winum, ace-window und scroll-other-window lassen sich nicht nur auf Fenster, sondern auf ganze Frames anwenden
  • Manche Emacs-Befehle setzen voraus, dass Frames beliebig geteilt werden können, weshalb Sonderfälle auftreten können
    • Besonders bei org-mode-Befehlen ist diese Tendenz zu beobachten
  • Es gibt keine Erfahrung mit frames-only-mode unter Wayland-Compositors

Sofortauswahl mit Nummern und Hinweisen

  • winum zeigt Fensternummern in der Mode-Line an und ermöglicht die Auswahl per Nummer
    • Wenn other-window eher nahe an O(n) liegt und windmove von der räumlichen Anordnung abhängt, bietet winum bei bekannter Nummer einen Zugriff nahe O(1)
    • Wird der Auswahlbefehl mit einem negativen Prefix-Argument aufgerufen, wird das entsprechende Fenster gelöscht
    • Wenn der Minibuffer aktiv ist, erhält er immer die Nummer 0
    • Funktioniert über Emacs-Frames hinweg
  • Der Standard-Tastaturbefehl C-x w <n> kann lang sein; als Beispiel wird eine Konfiguration genannt, die M-0 bis M-9 für die Fensterauswahl nutzt
  • ace-window wird als leistungsstarkes Werkzeug für die tastaturbasierte Fenstersteuerung in Emacs behandelt
    • Zeigt Hinweise über jedem Fenster an, die per Tastendruck zur Auswahl verwendet werden
    • Mit aktiviertem ace-window-display-mode können Hinweise wie bei winum dauerhaft in der Mode-Line angezeigt werden
    • Mit ? öffnet sich das Dispatch-Menü
  • Die Stärke von ace-window liegt weniger in der bloßen Auswahl als darin, nach der Fensterauswahl eine Aktion auszuführen
    • Fenster löschen
    • Fenster verschieben und tauschen
    • Fenster aufteilen
    • Bestimmten Buffer anzeigen
    • Aktionen auf andere Fenster anwenden, ohne das ausgewählte Fenster zu verlassen

Maus und Layout-Transformation

  • In Emacs passt die Maus ganz natürlich zu Fensterauswahl, Größenänderung, Kontextmenüs und Drag-and-Drop
    • context-menu-mode und die Menüleiste erhöhen die Auffindbarkeit
  • Wenn die Hände ohnehin schon nicht mehr auf der Tastatur sind, kann die Maus der Weg mit dem geringsten Widerstand sein, um Emacs zu bedienen
  • Auch per Mausgesten sind einige Aktionen möglich
    • Vertikale und horizontale Aufteilung des Frames
    • Fenster löschen
    • Durch Buffer innerhalb eines Fensters wechseln
    • Fenster nach rechts oder links tauschen
    • In einem Fenster zwischen den letzten zwei Buffern umschalten
  • Mit mouse-autoselect-window lässt sich focus-follows-mouse aktivieren
  • transpose-frame bietet Befehle zum Drehen oder Spiegeln des Fensterlayouts eines Frames
    • rotate-frame, flip-frame und flop-frame werden als besonders nützliche Befehle genannt
    • transpose-frame selbst wird als Transposition an der Hauptdiagonalen beschrieben und daher als praktisch weniger nützlich eingeschätzt

window-prefix-map und der Fensterbaum

  • window-prefix-map ist eine Sammlung von Fensterverwaltungsbefehlen, die in Emacs standardmäßig an C-x w gebunden ist
  • split-root-window-right und split-root-window-below teilen das Root-Fenster des Frames
    • Sie sind jeweils an C-x w 3 und C-x w 2 gebunden
    • Anders als normale Split-Befehle, die das aktuelle Fenster weiter aufteilen, sind sie nützlich, um separate Arbeitsbereiche anzulegen
  • Die Fenster in Emacs sind in einer Baumstruktur angeordnet
    • Tatsächliche Fenster sind Leaf-Knoten
    • Ein Split macht aus einem Leaf dessen Elternknoten für zwei Fenster
    • Das ähnelt der Anordnung manueller Tiling-Window-Manager wie i3 oder bspwm
  • tab-window-detach und tear-off-window verschieben das aktuelle Fenster in einen neuen Tab oder einen neuen Frame
    • Die Standard-Tastenkürzel C-x w ^ t und C-x w ^ f werden als lang eingeschätzt
    • Sie lassen sich durch ace-window-Dispatch-Aktionen oder Mausbindungen ersetzen

other-window-prefix: Ausgabeort des nächsten Befehls ändern

  • other-window-prefix ist ein eingebauter Befehl, der an C-x 4 4 gebunden ist und dafür sorgt, dass der vom nächsten Befehl angezeigte Buffer im nächsten Fenster erscheint
  • Dieser Befehl trennt bei Befehlen, die Buffer anzeigen, die Wahl des Buffers von der Wahl des Zielfensters
    • Dadurch muss man sich Befehlsfamilien wie find-file-other-window, find-file-other-tab oder find-file-other-frame nicht jedes Mal merken
    • Man kann einem Basisbefehl wie find-file, find-file-read-only oder switch-to-buffer einfach ein Prefix voranstellen und nur den Anzeigeort ändern
  • Im Forge-Beispiel lässt sich so vermeiden, dass beim Drücken von RET in der Issue-Liste das aktuelle Fenster überschrieben wird
  • Auch bei Paketen wie Magit, Org mode, Notmuch, Elfeed oder EWW sorgt das für einheitliches Verhalten, selbst wenn jedes Paket seinen eigenen Stil für „in anderem Fenster öffnen“ hat
  • Es gibt verwandte Prefixe
    • same-window-prefix erzwingt, dass der Buffer des nächsten Befehls im aktuellen Fenster erscheint
    • other-frame-prefix öffnet im neuen Frame
    • other-tab-prefix öffnet in einem neuen Tab

Fensterkonfigurationen speichern und wiederherstellen

  • window-configuration-to-register ist ein eingebauter Befehl zum Speichern der aktuellen Fensterkonfiguration in einem Register; das Standard-Tastenkürzel ist C-x r w
  • jump-to-register stellt eine gespeicherte Konfiguration wieder her; Standard-Tastenkürzel ist C-x r j
  • Auf Elisp-Ebene kann das Ergebnis von current-window-configuration in einer Variablen gespeichert und mit set-window-configuration angewendet werden
    • Speichert man es mit Methoden wie prin1, persist oder multisession auf Festplatte, ist das ein erster Baustein für Wiederherstellung zwischen Sitzungen
    • Allerdings werden dabei auch Cursorpositionen in jedem Fenster wiederhergestellt, was oft nicht erwünscht ist
  • Es gibt auch „Oops“-Optionen, die frühere Konfigurationen automatisch auf einen Stapel legen
    • winner-mode: Wenn keine Tabs verwendet werden, lassen sich Änderungen an Fensterkonfigurationen mit winner-undo und winner-redo rückgängig machen oder erneut anwenden
    • tab-bar-history-mode: Bietet für jeden Tab einen eigenen History-Stack
    • undelete-frame-mode und tab-undo: Stellen versehentlich geschlossene Frames oder Tabs wieder her
  • winner-undo jedes Mal als Rettungsanker zu nutzen, wenn Emacs Buffer an merkwürdigen Stellen öffnet, ist eher eine Behelfslösung
    • Das Grundproblem ist, dass die Regeln zur Buffer-Anzeige nicht wie gewünscht eingestellt sind

Für zwei oft genutzte Fenster optimieren

  • In der Praxis wechselt man auch bei vielen Fenstern auf dem Bildschirm meist häufig zwischen zwei Fenstern
    • Code & REPL
    • Code & Grep
    • Prosa & Notizen
    • Liste & Eintrag
  • Andere Fenster können eher Referenzbereiche sein, die man oft ansieht, aber kaum aktiv ansteuert, etwa für Dokumentation, Debug-Infos, Logs, Befehlsausgaben, Inhaltsverzeichnisse, Dateibrowser oder Vorschauen
  • Es gibt ein Beispiel für other-window-mru, das mit get-mru-window zum zuletzt verwendeten Fenster wechselt
    • Egal ob das zweite Fenster per Maus, ace-window, winum oder auf andere Weise gewählt wurde, danach kann man schnell hin- und herwechseln
  • Man kann auch other-window selbst verbessern
    • Automatisch splitten, wenn nur ein Fenster vorhanden ist
    • Wie bei switchy-window nach der Reihenfolge der letzten Nutzung rotieren
    • Wie bei other-window-alternating die Richtung bei jedem nicht direkt aufeinanderfolgenden Aufruf umkehren, damit sich das Pendeln zwischen zwei Fenstern natürlicher anfühlt

ace-window für befehlsbasierte Ausführung erweitern

  • ace-window kann über aw-select auch nur die Auswahlphase zum Bestimmen eines bestimmten Fensters separat nutzen
  • Führt man auf dem von aw-select zurückgegebenen Fenster eine gewünschte Aktion aus, entsteht das Muster „Fenster wählen → Aktion ausführen → ursprüngliches Fenster beibehalten“
  • Als Beispielbefehle werden genannt
    • ace-tear-off-window: Löst das mit ace-window gewählte Fenster in einen neuen Frame heraus
    • ace-tab-window-detach: Verschiebt das gewählte Fenster in einen neuen Tab
  • ace-window-one-command führt einen beliebigen einzelnen Befehl im ausgewählten Fenster aus
    • Zuerst wird mit ace-window ein Fenster gewählt
    • Dann wird eine Tastensequenz gelesen und der entsprechende Befehl ausgeführt
    • So lassen sich Aktionen auf andere Fenster anwenden, ohne das ursprünglich ausgewählte Fenster zu ändern
  • ace-window-prefix verhält sich wie eine direktere Version von other-window-prefix
    • Das Zielfenster für den vom nächsten Befehl angezeigten Buffer wird direkt mit ace-window gewählt
    • Falls nötig, kann per ace-window-Aktion sofort ein neues Fenster erzeugt und dort angezeigt werden
    • Als vorgeschlagene Tastenbindung wird C-x 4 o genannt

Muss man Fenster überhaupt wechseln?

  • Der Zweck des Fensterwechsels lässt sich grob in zwei Fälle einteilen
    • Switch and stay: Man bearbeitet oder nutzt das Zielfenster weiter
    • Switch and return: Man scrollt, sucht, kopiert oder löscht kurz etwas und kehrt dann an die ursprüngliche Position zurück
  • Im ersten Fall kann Avy Fensterwechsel und Cursorbewegung zu einem Vorgang zusammenfassen
    • avy-goto-char-timer behandelt mehrere sichtbare Emacs-Fenster und -Frames als einen einzigen Pool von Sprungzielen
    • Beim Sprung zu einer bestimmten Zeichenkette oder Zeichenposition wird automatisch auch das Fenster gewechselt
    • Wenn Avy nicht über Fenster und Frames hinweg arbeitet, sollte man die Einstellung avy-all-windows prüfen
  • pop-global-mark ist ein Mittel, um zur vorherigen Position zurückzukehren; falls nötig, kann dabei auch ein Fensterwechsel stattfinden
    • Standardmäßig wird dabei der Buffer im aktuellen Fenster gewechselt; es gibt ein Advice, das stattdessen pop-to-buffer verwenden lässt
  • Im zweiten Fall kann man den Ablauf „Wechsel → Aktion → Rückkehr“ in einen Befehl kapseln und automatisieren
    • ace-window-one-command ist eine allgemeine Methode dafür
    • Spezifische Aktionen lassen sich als eigene Befehle oder Makros umsetzen

Scrollen, Suchen und Buffer-Wechsel in anderen Fenstern

  • scroll-other-window und scroll-other-window-down scrollen ein anderes Fenster, ohne das aktuelle zu verlassen
    • Standardziel ist das „nächste Fenster“ im Uhrzeigersinn vom aktuellen Fenster aus
    • Bei drei oder mehr Fenstern kann dadurch ein anderes als das erwartete Referenzfenster gescrollt werden
  • Mit other-window-scroll-default lässt sich die Regel zur Auswahl des Scroll-Ziels ändern
    • Mit get-lru-window wird das am längsten nicht verwendete Fenster gescrollt
    • Mit get-mru-window kann das zuletzt verwendete Fenster als Ziel dienen
  • Setzt man other-window-scroll-buffer, kann man das Fenster mit einem bestimmten angezeigten Buffer als Scroll-Ziel festlegen
    • Diese Option wird vor allem als nützlich für Paketautoren behandelt
  • Das Beispiel isearch-other-window startet die Suche im Scroll-Zielfenster und kehrt nach Ende der Suche ins ursprüngliche Fenster zurück
    • Es gibt ein Beispiel mit Shell- und Man-Buffern
  • next-buffer, previous-buffer, switch-to-buffer lassen sich ebenfalls mit einem Prefix-Argument und other-window-for-scrolling so erweitern, dass sie in einem anderen Fenster ausgeführt werden
    • Erstellt man dafür eine Keymap für repeat-mode, kann man mit n, p, b Buffer in anderen Fenstern fortlaufend durchschalten oder auswählen

master-mode, scroll-all-mode, with-other-window

  • master-mode legt den aktuellen Buffer als „master“ und andere Buffer als „slave“ fest, sodass man Aktionen an Slave-Buffer senden kann, ohne die aktuelle Position zu verlassen
    • Grundsätzlich wird es als weniger transparente Alternative zum oben genannten Ansatz mit other-window-scroll-default bewertet
    • Über master-says lassen sich Tasten anlegen, die im Slave-Buffer beliebige Aktionen wie recenter ausführen
  • scroll-all-mode koppelt das Scroll-Verhalten aller Fenster innerhalb eines Frames
    • Das ist nützlich, wenn man mehrere Fensteransichten synchronisiert betrachten möchte
  • Das Makro with-other-window ist ein Elisp-Helfer, der den Hauptteil des Codes in dem von other-window-for-scrolling gewählten Fenster ausführt
    • Damit lassen sich Befehle wie isearch-other-window und isearch-other-window-backwards einfach erstellen
    • Es dient als Elisp-Gegenstück zum interaktiven ace-window-one-command

Strategien zur Verringerung der Fensterzahl

  • Moderne Editor-UIs laufen meist auf ein Hauptfenster, eine obere Tab-Leiste, eine linke Seitenleiste für Verzeichnisse oder Inhaltsverzeichnisse, ein optionales rechtes Panel und ein unteres Terminal hinaus
  • Auch in Emacs lässt sich ein solches Layout bauen, aber man kann den Bildschirm auch auf einen Buffer konzentrieren und Buffer-Wechsel als Ersatz für Fensterwechsel nutzen
  • Wenn man nur bis zu zwei Fenster zulässt, bleibt der Großteil der Einfachheit erhalten, während das zweite Fenster als Live-Referenzmaterial dienen kann
    • Die Emacs-Standardeinstellungen unterstützen dieses Muster mit Befehlen wie scroll-other-window bereits recht gut
  • Es gibt auch die Strategie, Fenster nur als Textcontainer zu betrachten und weitgehend zu ignorieren
    • Mit Avy springt man direkt zu Textpositionen auf dem Bildschirm
    • Mit mark-ring und global-mark-ring verfolgt man frühere Positionen zurück
    • dogears kann dafür eine feinere UI zum Zurückverfolgen bieten
  • Für manuelles Fixieren von Positionen kann man point-to-register und jump-to-register verwenden; für dauerhaftigere Aufzeichnungen bookmark-set und bookmark-jump

Regeln für automatische Anzeige und Popup-Verwaltung

  • display-buffer-alist ist die Variable, die beim Anzeigen eines Buffers durch Elisp-Code Buffer und Regeln abgleicht, um die Darstellungsweise zu bestimmen
  • Theoretisch ließe sich ein großer Teil der Fensterverwaltung lösen, wenn man für jeden täglich genutzten Buffertyp Regeln zu Größe, Position, Rolle und Fokus erstellt
  • Das Problem sind die Einrichtungskosten
    • Buffer- und Modus-Predicates
    • Fenstertypen und Slots
    • display-buffer-Action-Funktionen
    • Fensterparameter
    • Einfache Absichten wie „Meine Fensteranordnung nicht verändern“ lassen sich nicht leicht ausdrücken
  • Es gibt auch Hilfswerkzeuge
    • Shackle verdeckt die Komplexität von display-buffer-alist und bietet eine einfache Elisp-Schnittstelle
    • Doom Emacs bietet Komfortbefehle wie set-popup-rule!
  • Popwin und Popper gehen von der Beobachtung aus, dass nicht alle Buffer gleich sind
    • Sie unterscheiden zwischen Hauptarbeits-Buffern und temporären Popup-Buffern
    • Dokumentation, Shell, Arbeitsstatus, Compilergebnisse, Suchergebnisse, Nachrichten usw. werden in kleinen Hilfsfenstern geöffnet und lassen sich leicht schließen oder durchschalten
    • Popper konzentriert sich darauf, festgelegte Popup-Buffer mit einer Taste ein- und auszublenden
    • Popwin ist eine ältere und umfassendere Implementierung, bündelt dafür aber auch eine eigene display-buffer-Konfiguration mit ein
    • Wenn man nur schnell eine Shell ein- und ausblenden möchte, können shell-pop oder vterm-toggle ausreichen

Das fehlende Puzzlestück: Manipulation des Fensterbaums

  • Emacs stellt Fenster innerhalb eines Frames als Baum dar, aber die meisten Benutzerbefehle arbeiten nicht mit der Baumstruktur, sondern nur mit der räumlichen Position
  • Wegen dieser Inkonsistenz kann es beim Teilen oder Löschen zu unerwartetem Verhalten kommen, oder es entstehen Einschränkungen bei den möglichen Teilungsstrukturen
  • Wenn es ein hypothetisches Paket wie window-tree gäbe, könnte man Operationen auf Ebene interner Knoten ermöglichen
    • Nur Teile eines Frames teilen, transponieren oder spiegeln
    • Mehrere Fenster als Teilkonfiguration auswählen
    • Die ausgewählte Teilkonfiguration an Tabs oder Frames übergeben
    • Teilkonfigurationen duplizieren oder speichern
    • Einen bestimmten Branch des Baums vor Befehlen der display-buffer-Familie schützen
  • Es gibt bereits vorhandene Elisp-Bausteine
    • window-tree gibt den Baum selbst zurück
    • frame-root-window gibt die Wurzel zurück
    • Es gibt window-parent, window-child, window-*-sibling
    • Mit walk-window-tree und walk-windows kann man ihn traversieren
  • Auch die Defizite sind klar
    • Außer den allgemeinen Split/Delete-Operationen gibt es keine Grundfunktionen, die den Baum umformen
    • Es gibt kein Konzept, ein internes Fenster auszuwählen; das muss über die UI simuliert werden

Das fehlende Puzzlestück: Integration mit tiling Window Managern

  • Das Fenstermodell von Emacs in Baumstruktur ist manuellen tiling Window Managern wie i3 oder bspwm sehr ähnlich
  • Wer Emacs innerhalb von i3, bspwm oder tmux nutzt, möchte mit denselben Keybindings ganz natürlich zwischen Fenstern innerhalb und außerhalb von Emacs wechseln
  • Vorhandene Beispiele sind Pavel Korytovs i3-integration und emacs-wm.el für qtile
  • Eine sauberere Integrationsschnittstelle braucht die folgenden Elemente
    • Der Window Manager muss die Klasse des aktiven Fensters erkennen und programmatischen Zugriff auf Fensterbewegung und -manipulation bieten
    • Als Kommunikationsweg kommen Shell-Befehle, Sockets, serverbasierte IPC oder D-Bus unter Linux infrage
    • Auf Emacs-Seite braucht es eine von der Kommunikationsmethode unabhängige Schnittstelle, die Bedienung im Stil eines Window Managers nachbildet
    • Beim Wechseln von OS-Fenstern wird geprüft, ob das aktive Fenster Emacs ist; falls nötig verarbeitet Emacs die Aktion im internen Frame

Fazit

  • Die Fensterverwaltung in Emacs bietet auf verschiedenen Ebenen Optionen, von other-window über ace-window, Avy und Popper bis zu display-buffer-alist
  • Man muss nicht alle Methoden verwenden; weil es viele Alternativen für dieselben Probleme gibt, kann man eine auswählen und den Rest ignorieren
  • Die eingebauten Standardwerkzeuge werden wahrscheinlich lange erhalten bleiben, während sich der Zustand von Drittanbieter-Paketen je nach Weiterentwicklung, Vernachlässigung oder Verwaisung ändern kann
  • Die Fensterverwaltung von Emacs ist weniger ein komplexes starres System als vielmehr eine offene Struktur, die Zutaten und Rezepte bereitstellt
  • Schon mit wenig Konfiguration ist eine Grundversorgung möglich, und mit etwas Kombination sowie Elisp-Anpassungen lässt sich ein deutlich stärker personalisierter Workflow aufbauen

1 Kommentare

 
GN⁺ 2024-05-13
Hacker-News-Kommentare
  • Guter Artikel, und auch die Erklärungen und Richtlinien sind hervorragend. Manchmal reichen gleichmäßig geteilte Fenster nicht aus, daher habe ich die folgenden Funktionen in init.el eingefügt und auf C-x 7 gelegt, um das aktuelle Fenster und das dazugehörige Fenster vertikal auf 70 %/30 % zu setzen.
    Für die horizontale Richtung mache ich mit der Belegung auf C-x 8 dasselbe.

    (defun partial-size-window ()
    "Set the two split windows to 70% and 30% vertically."
    (interactive)
    (let ((size (- (truncate (* .70 (frame-height))) (window-height))))
    (if (> size 0)
    (enlarge-window size))))

    (defun partial-size-window-h ()
    "Set the two split windows to 70% and 30% horizontally."
    (interactive)
    (let ((size (- (truncate (* .70 (frame-width))) (window-width))))
    (if (> size 0)
    (enlarge-window-horizontally size))))

    • golden-ratio kann man ebenfalls für so etwas verwenden.
  • Interessante Untersuchung. Ich bin gerade mobil unterwegs und kann es nicht sofort ausprobieren, aber ich möchte ace-window, ace-window-display-mode und frames-only-mode möglichst bald testen.
    Ehrlich gesagt muss ich gestehen, dass ich Emacs in rund 40 Jahren meist nur mit next-window, dem Erstellen neuer Fenster unten oder daneben und bei Arbeit auf Remote-Servern mit tmux genutzt habe.

    • Bei mir ähnlich. 30 Jahre lang war es fast nur C-x 1/2/3 und C-x o.
      Das ist allerdings tatsächlich ziemlich mächtig und für meine Zwecke ausreichend, und ich denke oft, mehrere Tiling Window Manager sollten im Grunde genau so sein.
    • Bei mir ähnlich. C-x o ist etwas umständlich, daher habe ich die folgende Einstellung gesetzt, aber ich habe nicht unbedingt das Gefühl, dass man solche Zusatzpakete wirklich braucht.
      (global-set-key (kbd "M-o") #'other-window)
      Trotzdem ist es schön, solch einen tiefgehenden Referenzartikel zu haben, und Karthiks Beiträge sind immer lehrreich und interessant.
  • Ergänzend zu Karthinks Hinweis zu windmove-mode: Man kann windmove-default-keybindings setzen, um mit Ctrl-<Pfeiltaste> zwischen Fenstern zu wechseln.
    (windmove-default-keybindings 'control)
    Ich habe das auch in meiner Konfiguration und sogar in einem minimalistischen Starter-Kit drin, und es ist wirklich ein Game Changer.
    https://codeberg.org/ashton314/emacs-bedrock

    • Ich habe in meiner .emacs nachgesehen und nutze exakt dasselbe. Gegenüber C-x O ist ein Tastendruck weniger nötig und es ist flexibler, deshalb bevorzuge ich es.
  • Ich habe Emacs so konfiguriert, dass ein Frame nicht in mehrere Fenster geteilt wird. Das ist ähnlich wie ein Webbrowser, der ein Browserfenster nicht in mehrere Viewports aufteilt.
    Mein Emacs erstellt auch keinen zweiten Frame. Da die alte Vorgehensweise nicht mehr funktioniert, hat sich die Umsetzung im Lauf der Jahre immer wieder geändert.
    In der aktuellen Variante wird der Frame in bestimmten Situationen dennoch geteilt, zum Beispiel wenn Emacs den Buffer *Completions* anzeigt, aber soweit ich mich erinnere, musste ich delete-window nie manuell aufrufen, um das zweite Fenster zu entfernen, und es verschwand immer von selbst.

    • Webbrowser können Fenster tatsächlich so aufteilen, wenn es ein Browser wie Vivaldi ist, mit dem man mehrere Seiten gleichzeitig anzeigen kann.
    • Mich würde interessieren, ob das Verhindern der Aufteilung eines Frames in mehrere Fenster ein bestimmtes Problem lösen sollte.
      Ich nutze Frames mit mehreren Fenstern ziemlich häufig. Auf aktuellem macOS und aktuellem Emacs kommt es bei mir gelegentlich vor, dass ein Frame mit mehreren Fenstern nicht mehr auf Tastatur oder Trackpad reagiert und eingefroren wirkt; auch mehrfaches Drücken von Ctrl-G hilft dann nicht.
      Das Erstellen eines neuen Frames mit C-x 5 2 funktioniert jedoch, und wenn ich zum eingefrorenen Frame zurückkehre, kann ich ihn mit C-x 5 0 schließen.
  • Der Artikel geht sehr in die Tiefe, und mir gefällt besonders, dass der Autor Zeit investiert hat, gute Diagramme zu erstellen.

  • Guter Artikel, und ich möchte ein großartiges Paket empfehlen, das gut dazu passt. Für mich war zygospore unverzichtbar.
    „zygospore erlaubt es, C-x 1 (delete-other-window) rückgängig zu machen, indem man C-x 1 erneut drückt“
    https://github.com/LouisKottmann/zygospore.el

    • Wenn man alle Änderungen an der Fensterkonfiguration wiederholen oder rückgängig machen möchte, lohnt sich ein Blick auf winner mode.
      https://www.emacswiki.org/emacs/WinnerMode
    • Im Idealfall sollte das vielleicht undo sein.
      Es wäre zwar etwas seltsam, aber C-u C-x 1 würde immerhin konsistent wirken.
  • Falls der Autor das hier sieht: Ich wollte nur sagen, dass ich mich über die kleine Erwähnung des Acme editor gefreut habe.

  • Wenn ich hledger-balance-sheet aufrufe, möchte ich, dass es sich rechts mit 30 % Breite öffnet, ohne die bestehende .hledger.journal zu ersetzen.
    Links soll .hledger.journal geöffnet und ausgewählt bleiben.