Tree-based workspace management for Emacs. Supports Emacs 28.1+.
space-tree is a library for managing spaces (workspaces) in Emacs. It is inspired by the concept of "workspaces" supported in most major operating systems' window managers, and is intended to be a lightweight but flexible alternative to packages like tab-bar-mode and eyebrowse.
- Tree-based structure: Organize spaces hierarchically with branches of mixed and arbitrary depth
- Modeline indicator: Visual indication of the current space and context in the space-tree
- Navigation commands: Create, switch, copy, paste, and manage spaces
(use-package space-tree
:ensure (:host github :repo "chiply/space-tree")
:config
(space-tree-init))(use-package space-tree
:straight (:host github :repo "chiply/space-tree")
:config
(space-tree-init))Clone the repository and add it to your load-path:
(add-to-list 'load-path "/path/to/space-tree")
(require 'space-tree)
(space-tree-init)| Command | Description |
|---|---|
space-tree-init |
Initialize or reset space-tree |
space-tree-switch-or-create |
Switch to a space or create it if it doesn't exist |
space-tree-create-space-current-level |
Create a new space at the current level |
space-tree-create-space-top-level |
Create a new space at the top level |
space-tree-delete-space |
Delete a space |
space-tree-go-right |
Switch to the next space to the right |
space-tree-go-left |
Switch to the next space to the left |
space-tree-go-to-last-space |
Switch to the most recently visited space |
space-tree-switch-space-by-name |
Switch to a named space |
space-tree-name-current-space |
Name the current space |
space-tree-name-space-by-digit-arg |
Name a space specified by digit prefix arg |
space-tree-switch-current-level |
Switch to a space at the current level by number |
space-tree-switch-space-by-digit-arg |
Switch to a space using a digit-encoded address |
space-tree-copy-workspace |
Copy the current workspace |
space-tree-paste-workspace |
Paste the copied workspace |
Add space-tree-modeline-lighter to your modeline to see the current space:
(setq-default mode-line-format
'(...
(:eval (space-tree-modeline-lighter))
...))For binding directly to keys, the package defines a family of commands that switch to a fixed space at each of the first three levels:
| Command family | What it switches to |
|---|---|
space-tree-to-1 … space-tree-to-9 |
Top-level space N |
space-tree-sub-1 … space-tree-sub-5 |
Sub-space N of the current top-level |
space-tree-sub-sub-1 … space-tree-sub-sub-5 |
Sub-sub-space N of the current sub |
These exist so you can bind keys without writing a lambda per binding.
For deeper levels or non-contiguous targets, write a small wrapper
around space-tree-switch-or-create that passes an explicit address.
Here's an example configuration using general.el for keybindings:
(use-package space-tree
:straight (:host github :repo "chiply/space-tree")
:config
(space-tree-init)
;; Top-level spaces with Super key + number
(general-define-key
"s-1" #'space-tree-to-1
"s-2" #'space-tree-to-2
"s-3" #'space-tree-to-3
"s-4" #'space-tree-to-4
"s-5" #'space-tree-to-5
"s-6" #'space-tree-to-6
"s-7" #'space-tree-to-7
"s-8" #'space-tree-to-8
"s-9" #'space-tree-to-9
;; Second level (within current top-level space)
"s-a" #'space-tree-sub-1
"s-s" #'space-tree-sub-2
"s-d" #'space-tree-sub-3
"s-f" #'space-tree-sub-4
"s-g" #'space-tree-sub-5
;; Third level (within current second-level space)
"s-A" #'space-tree-sub-sub-1
"s-S" #'space-tree-sub-sub-2
"s-D" #'space-tree-sub-sub-3
"s-F" #'space-tree-sub-sub-4
"s-G" #'space-tree-sub-sub-5
;; Navigation
"M-S-<tab>" #'space-tree-switch-space-by-name
"M-<tab>" #'space-tree-go-to-last-space
"C-M-<tab>" #'space-tree-go-right
"C-M-S-<tab>" #'space-tree-go-left
;; Delete current space (the command defaults to the current address)
"s-_" #'space-tree-delete-space)
;; Evil/vim-style bindings
(general-define-key
:states '(normal visual)
:keymaps 'override
"gt" #'space-tree-switch-current-level
"gT" #'space-tree-switch-space-by-digit-arg
"g+" #'space-tree-create-space-top-level
"gn" #'space-tree-create-space-current-level))If non-nil, the first space will be numbered 0. Otherwise, the first space will be numbered 1.
(setq space-tree-start-at-0 t)space-tree organizes workspaces in a tree structure. Each node in the tree can have multiple children, allowing for hierarchical organization:
Space 1
├── Space 1.1
│ ├── Space 1.1.1
│ └── Space 1.1.2
├── Space 1.2
└── Space 1.3
Space 2
├── Space 2.1
└── Space 2.2
Space 3
Each space stores its own window configuration, which is restored when you switch to that space.
- Emacs 28.1+ (no external packages)
GPL-3.0-or-later. See LICENSE for details.