space-tree: Workspace Management Trees in Emacs

https://lobste.rs/rss Hits: 16
Summary

The implementation is small, by design. The whole thing, including docstrings, is ~680 lines of code at the time of this writing, and it could have been smaller if I'd used dash or ht. At its core, space-tree is two simple ideas (plus a sparse third for names): A tree of addresses. Each space is identified by a list of integers, read left to right as a path down the tree. (2 1 3) means "start at top-level space 2, descend to its 1st child, then to that child's 3rd child." The tree itself lives in a nested hash table whose values are hash tables, recursively. Creating a space writes a new key, and deleting a space removes a subtree. A hash table from address to window state. When you switch to a space, the saved state is restored; when you leave one, the live state is snapshotted back. Branching creates a new address and seeds it with a fresh layout. The native Emacs API is doing all the heavy lifting of storing and restoring the window layouts. The "window state" is what the built-in window-state-get returns, and what window-state-put accepts. These are the canonical Emacs primitives for serializing the arrangement of windows and their buffers in a frame, available since Emacs 24. space-tree adds no new representation of what a layout is. The only thing it adds is a shape for organizing many layouts at once. To make the two ideas concrete: suppose a user has carved out the following spaces over the course of a session. 1 ├── 1.1 │ └── 1.1.1 └── 1.2 2 The three hash tables of space-tree then look like this, assuming the user has named two of the spaces: ;; space-tree-tree — the *shape*, as a nested hash table. ;; Keys are integer space numbers; values are child hash tables. { 1 → { 1 → { 1 → {} }, 2 → {} }, 2 → {} } ;; space-tree-address-wconf-tbl — the *snapshots*, as a flat hash table. ;; Keys are address lists; values are what `window-state-get' returns. { (1) → #<window-state ...>, (1 1) → #<window-state ...>, (1 1 1) → #<window-state ...>, (1 2) → #<window-state...

First seen: 2026-05-27 12:52

Last seen: 2026-05-28 04:01