Keyboard-driven, column-oriented pane management for Herdr, inspired by the workflow of the wmii tiling window manager.
The plugin treats a tab as ordered logical columns, with each column containing an ordered vertical stack of live panes. Panes can be moved directionally or an arbitrary existing layout can be rebuilt into one to four canonical columns.
left/rightmoves the active pane to the bottom of the adjacent column.- Moving the last pane out of a column removes that column.
- Moving outward from an edge creates a new column when the source stack has other panes.
up/downreorders panes inside the current column.- Rebuild actions convert any binary pane tree into 1–4 equal-width columns.
- Live PTYs, running processes, scrollback, terminal identity, and focus are preserved.
- Ambiguous failures are reconciled before rollback.
- Concurrent actions are serialized per Herdr session.
The directional model deliberately has no wrap-around.
wmii made columns and keyboard-driven movement first-class. This plugin applies the same idea to terminal panes:
┌──────────┬──────────┬──────────┐
│ pane A │ pane C │ pane F │
├──────────┤ ├──────────┤
│ pane B │ │ pane G │
└──────────┴──────────┴──────────┘
- Horizontal movement transfers a pane between columns.
- Vertical movement changes its position inside a column.
- Column widths and pane heights are normalized.
- Unsupported trees can be rebuilt explicitly instead of being guessed during movement.
This is workflow inspiration, not an implementation of wmii's window-management protocol.
- Herdr
0.8.2or newer - Node.js
18or newer - macOS or Linux
Install directly from GitHub:
herdr plugin install geshido/herdr-column-layoutFor local development:
git clone https://github.com/geshido/herdr-column-layout.git
herdr plugin link ./herdr-column-layout| Action | Behavior |
|---|---|
move-left |
Move the active pane one column left |
move-right |
Move the active pane one column right |
move-up |
Move the active pane up within its column |
move-down |
Move the active pane down within its column |
rebuild-1 … rebuild-4 |
Rebuild the tab into the requested number of columns |
The plugin does not modify your Herdr keybindings. A wmii-style setup:
[[keys.command]]
key = "cmd+alt+left"
type = "plugin_action"
command = "geshido.column-layout.move-left"
[[keys.command]]
key = "cmd+alt+right"
type = "plugin_action"
command = "geshido.column-layout.move-right"
[[keys.command]]
key = "cmd+alt+up"
type = "plugin_action"
command = "geshido.column-layout.move-up"
[[keys.command]]
key = "cmd+alt+down"
type = "plugin_action"
command = "geshido.column-layout.move-down"
[[keys.command]]
key = "cmd+alt+1"
type = "plugin_action"
command = "geshido.column-layout.rebuild-1"
# Repeat for rebuild-2, rebuild-3, and rebuild-4.If the terminal emulator consumes these shortcuts, unbind them there. For Ghostty:
keybind = super+alt+arrow_left=unbind
keybind = super+alt+arrow_right=unbind
keybind = super+alt+arrow_up=unbind
keybind = super+alt+arrow_down=unbind
keybind = super+alt+1=unbind
keybind = super+alt+2=unbind
keybind = super+alt+3=unbind
keybind = super+alt+4=unbindRebuild reads panes in visual order—top to bottom, then left to right—and distributes them row-major across the requested number of columns.
For four panes rebuilt into two columns:
Before reading order: A, B, C, D
After: [A, C] [B, D]
If fewer panes exist than requested columns, the number of columns is capped to the pane count.
Herdr currently cannot reparent a live pane within the same tab atomically. The plugin therefore stages panes through a temporary tab and immediately inserts them into the target tree.
- Public Herdr CLI commands perform the fast pane mutations.
- The socket API is used only for operations without CLI equivalents.
- Pane IDs are reconciled by terminal identity after ambiguous outcomes.
- Rollback can reconstruct the original arbitrary binary tree.
- Lock claim files are owner-checked and written with user-only permissions.
SIGINTandSIGTERMtrigger bounded cleanup.
layout.apply is intentionally not used because replacing the tab would lose live PTYs and scrollback.
npm test
herdr config checkThe test suite uses Node's built-in test runner and has no runtime dependencies.
MIT — see LICENSE.