https://github.com/gufranco/tmux-tiling-revamped
BSP tiling window management for tmux. Dwindle, spiral, grid, main-center, monocle, and deck layouts with auto-reapplication and zero dependencies
https://github.com/gufranco/tmux-tiling-revamped
bash bsp bspwm dwindle dwm hyprland i3 spiral tiling tmux tmux-plugin tpm window-management
Last synced: about 1 month ago
JSON representation
BSP tiling window management for tmux. Dwindle, spiral, grid, main-center, monocle, and deck layouts with auto-reapplication and zero dependencies
- Host: GitHub
- URL: https://github.com/gufranco/tmux-tiling-revamped
- Owner: gufranco
- License: mit
- Created: 2026-03-20T17:18:15.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-01T18:10:19.000Z (2 months ago)
- Last Synced: 2026-04-02T05:30:22.980Z (2 months ago)
- Topics: bash, bsp, bspwm, dwindle, dwm, hyprland, i3, spiral, tiling, tmux, tmux-plugin, tpm, window-management
- Language: Shell
- Size: 133 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
tmux-tiling-revamped
BSP tiling window management for tmux. Eight layouts, seventeen operations, zero dependencies.
[](https://github.com/gufranco/tmux-tiling-revamped/actions/workflows/tests.yml)
[](LICENSE)
[](CHANGELOG.md)
[](https://github.com/tmux/tmux)
[](https://www.gnu.org/software/bash/)
---
**8** layouts · **16** BSP orientations · **17** operations · **30+** commands · **528** tests · **zero** dependencies
### BSP Tiling
Dwindle and spiral layouts with 16 orientation variants and configurable first-split ratio. Panes cascade into binary space partitions toward any corner.
### Layout Undo
Every layout change is saved to a per-window history stack. One keystroke reverts to the previous arrangement. Up to 10 levels deep.
### i3-Style Workspaces
Alt+1-9 switches windows. Alt+Shift+1-9 moves panes between windows. International keyboard support via configurable Shift+number mappings.
### fzf Layout Picker
Interactive popup with ASCII diagram previews for all 8 layouts. Shows current layout in the header. Configurable popup dimensions.
### Balanced Distribution
Main-center distributes extra panes evenly between left and right columns. All layouts verified balanced at pane counts 1-10 with 48 dedicated tests.
### Diagnostics Built In
`doctor` checks your environment. `info` shows current state. `validate` detects stale metadata. `help` prints a complete reference from the terminal.
## Why
tmux has five built-in layouts. None do BSP tiling. Existing plugins each solve a piece but leave gaps.
| Capability | tiling-revamped | tmux-tilish | tmux-tilit |
|:-----------|:---------------:|:-----------:|:----------:|
| BSP dwindle + spiral | Yes | No | No |
| 16 orientation variants | Yes | No | No |
| Configurable split ratio | Yes | No | No |
| Layout undo/redo | Yes | No | No |
| Layout picker (fzf) | Yes | No | No |
| Balanced main-center | Yes | No | No |
| Workspace switching | Yes | Yes | Yes |
| Project launcher | Yes | Yes | No |
| Pane marks | Yes | No | No |
| Scratchpads | Yes | No | No |
| Presets (save/restore) | Yes | No | No |
| Health check (doctor) | Yes | No | No |
| tmux-resurrect integration | Yes | No | No |
| Rotate / flip | Yes | No | No |
| Auto-reapplication | Yes | Yes | Yes |
| Vim-aware navigation | Yes | Yes | Yes |
| International keyboards | Yes | Yes | Yes |
## Architecture
```mermaid
graph LR
K[Keybinding] --> D[tiling.sh
Dispatcher]
H[tmux Hook] --> D
D --> L[Layouts
8 modules]
D --> O[Operations
17 modules]
D --> F[Features
7 modules]
L --> T[Batched tmux
Commands]
O --> T
F --> T
T --> S[(tmux State
User Options)]
S -.->|auto-reapply| H
```
State is stored in tmux user options at window, pane, or global scope. No temp files, no external state.
## Layouts
### Dwindle
BSP cascade toward a corner. Each new pane takes half of the remaining space.
**4 panes**
```
┌───────────────────┬───────────────────┐
│ │ │
│ │ 2 │
│ 1 │ │
│ ├─────────┬─────────┤
│ │ │ │
│ │ 3 │ 4 │
└───────────────────┴─────────┴─────────┘
```
### Spiral
Same BSP algorithm as dwindle, but the spiral trajectory reverses pane ordering at each depth. The frame is identical to dwindle, only the pane numbers differ.
**4 panes**
```
┌───────────────────┬───────────────────┐
│ │ │
│ │ 2 │
│ 1 │ │
│ ├─────────┬─────────┤
│ │ │ │
│ │ 4 │ 3 │
└───────────────────┴─────────┴─────────┘
```
### Grid
Even N x M grid. Uses tmux's built-in tiled layout.
**4 panes**
```
┌───────────────────┬───────────────────┐
│ │ │
│ 1 │ 2 │
│ │ │
├───────────────────┼───────────────────┤
│ │ │
│ 3 │ 4 │
│ │ │
└───────────────────┴───────────────────┘
```
### Main-Center
Wide center pane with balanced side columns. Extra panes distribute evenly.
**6 panes**
```
┌─────────┬───────────────────┬─────────┐
│ 2 │ │ 4 │
├─────────┤ ├─────────┤
│ 3 │ 1 │ 5 │
│ │ ├─────────┤
│ │ │ 6 │
└─────────┴───────────────────┴─────────┘
```
### Main-Vertical
Master left, stack right. Master size controlled by `@tiling_revamped_master_ratio`.
**4 panes**
```
┌───────────────────┬───────────────────┐
│ │ 2 │
│ ├───────────────────┤
│ 1 │ 3 │
│ ├───────────────────┤
│ │ 4 │
│ │ │
└───────────────────┴───────────────────┘
```
### Main-Horizontal
Master top, stack bottom. Master size controlled by `@tiling_revamped_master_ratio`.
**4 panes**
```
┌───────────────────────────────────────┐
│ │
│ 1 │
│ │
├───────────┬───────────┬───────────────┤
│ 2 │ 3 │ 4 │
└───────────┴───────────┴───────────────┘
```
### Monocle
Zoom the focused pane to fill the entire window. Press the same key again to toggle zoom off and restore the previous layout.
```
┌───────────────────────────────────────┐
│ │
│ │
│ 1 │
│ [ZOOMED] │
│ │
│ │
└───────────────────────────────────────┘
(other panes hidden behind)
```
### Deck
All panes at full height, side by side at equal widths.
**4 panes**
```
┌─────────┬─────────┬─────────┬─────────┐
│ │ │ │ │
│ │ │ │ │
│ 1 │ 2 │ 3 │ 4 │
│ │ │ │ │
│ │ │ │ │
└─────────┴─────────┴─────────┴─────────┘
```
## Quick Start
### Prerequisites
| Tool | Version | Install |
|:-----|:--------|:--------|
| tmux | 3.2+ | [github.com/tmux/tmux](https://github.com/tmux/tmux) |
| bash | 4.0+ | Ships with Linux. macOS: `brew install bash` |
| TPM | latest | [github.com/tmux-plugins/tpm](https://github.com/tmux-plugins/tpm) |
| fzf | 0.44.0+ | Optional. Enables layout picker, fuzzy mark/preset selection |
### Install
Add to `~/.tmux.conf`:
```tmux
set -g @plugin 'gufranco/tmux-tiling-revamped'
```
Press `prefix + I` to install via TPM.
### Verify
Open tmux, create a few panes, then press `prefix + d`. All panes rearrange into a dwindle layout.
## Default Keybindings
All keybindings use the tmux prefix. Every key is configurable via `@tiling_revamped_key_*` options.
| Key | Action | Command |
|:----|:-------|:--------|
| `d` | Apply dwindle layout | `layout dwindle` |
| `D` | Apply spiral layout | `layout spiral` |
| `v` | Apply main-vertical layout | `layout main-vertical` |
| `V` | Apply main-horizontal layout | `layout main-horizontal` |
| `b` | Balance panes | `balance` |
| `B` | Equalize panes | `equalize` |
| `m` | Promote focused pane to master | `promote` |
| `.` | Rotate layout 90 degrees | `rotate` |
| `,` | Flip layout horizontally | `flip` |
| `C-r` | Circulate panes | `circulate` |
| `C-d` | Smart split along longest axis | `autosplit` |
| `o` | Cycle to next layout | `cycle` |
| `+` | Grow master pane | `resize-master grow` |
| `-` | Shrink master pane | `resize-master shrink` |
| `S` | Toggle synchronize panes | `sync` |
| `M` | Mark pane with a name | `mark ` |
| `j` | Jump to marked pane | `jump` |
| `g` | Toggle scratchpad popup | `scratchpad` |
| `p` | Open layout picker | `pick` |
| `u` | Undo last layout change | `undo` |
## Configuration
All options use the `@tiling_revamped_` prefix.
### Behavior
| Option | Default | Description |
|:-------|:--------|:------------|
| `@tiling_revamped_auto_apply` | `1` | Reapply layout when panes are added or removed |
| `@tiling_revamped_default_layout` | (empty) | Auto-apply this layout on new windows |
| `@tiling_revamped_default_orientation` | `brvc` | Default BSP orientation for new windows |
| `@tiling_revamped_focus_resize` | `0` | Expand focused pane toward golden ratio on focus |
| `@tiling_revamped_focus_ratio` | `62` | Percentage of window for focused pane |
| `@tiling_revamped_master_ratio` | `60` | Master pane percentage for main-vertical and main-horizontal |
| `@tiling_revamped_main_center_ratio` | `60` | Width percentage for main-center center pane |
| `@tiling_revamped_split_ratio` | `50` | First BSP split ratio (20-80). Useful for ultrawide monitors |
| `@tiling_revamped_resize_step` | `5` | Percentage step for resize-master grow/shrink |
| `@tiling_revamped_cycle_layouts` | `dwindle spiral grid main-vertical main-horizontal main-center monocle deck` | Layout cycle order |
| `@tiling_revamped_alt_keys` | `0` | Use Alt keybindings (`M-`) instead of prefix mode |
| `@tiling_revamped_navigator` | `0` | Vim-aware navigation. Set to `1` to enable `M-h/j/k/l` with vim detection |
| `@tiling_revamped_workspaces` | `0` | Enable i3-style Alt+1-9 workspace switching |
| `@tiling_revamped_shiftnum` | `!@#$%^&*()` | Shift+number characters for international keyboards |
| `@tiling_revamped_project_dir` | (empty) | Root directory for project launcher |
| `@tiling_revamped_project_depth` | `1` | Subdirectory depth for project search |
| `@tiling_revamped_scratch_width` | `80%` | Scratchpad popup width |
| `@tiling_revamped_scratch_height` | `75%` | Scratchpad popup height |
| `@tiling_revamped_pick_width` | `60%` | Layout picker popup width |
| `@tiling_revamped_pick_height` | `40%` | Layout picker popup height |
| `@tiling_revamped_pick_preview_width` | `60%` | Layout picker preview panel width |
| `@tiling_revamped_min_pane_width` | `10` | Minimum pane width before layout refuses to apply |
| `@tiling_revamped_min_pane_height` | `5` | Minimum pane height before layout refuses to apply |
| `@tiling_revamped_enable_logging` | `0` | Write debug logs to `~/.tmux/tiling-logs/` |
### Custom Keybindings
```tmux
set -g @tiling_revamped_key_dwindle "d"
set -g @tiling_revamped_key_spiral "D"
set -g @tiling_revamped_key_main_vertical "v"
set -g @tiling_revamped_key_main_horizontal "V"
set -g @tiling_revamped_key_balance "b"
set -g @tiling_revamped_key_equalize "B"
set -g @tiling_revamped_key_promote "m"
set -g @tiling_revamped_key_rotate "."
set -g @tiling_revamped_key_flip ","
set -g @tiling_revamped_key_circulate "C-r"
set -g @tiling_revamped_key_autotile "C-d"
set -g @tiling_revamped_key_cycle "o"
set -g @tiling_revamped_key_master_grow "+"
set -g @tiling_revamped_key_master_shrink "-"
set -g @tiling_revamped_key_sync "S"
set -g @tiling_revamped_key_mark "M"
set -g @tiling_revamped_key_jump "j"
set -g @tiling_revamped_key_scratchpad "g"
set -g @tiling_revamped_key_pick_layout "p"
set -g @tiling_revamped_key_undo "u"
set -g @tiling_revamped_key_project ""
# Directional swap (disabled by default, set keys to enable)
set -g @tiling_revamped_key_swap_up ""
set -g @tiling_revamped_key_swap_down ""
set -g @tiling_revamped_key_swap_left ""
set -g @tiling_revamped_key_swap_right ""
```
Set any key to `""` (empty string) to disable that binding entirely.
### Avoiding Key Conflicts in Prefix Mode
Several default keys conflict with common tmux bindings.
| Default Key | Conflicts With | Suggested Alternative |
|:------------|:---------------|:----------------------|
| `b` (balance) | `prefix + b` lists paste buffers | `=` |
| `M` (mark) | `prefix + M` is often used for scrollback | `N` |
| `j` (jump) | `prefix + j` navigates panes down | `G` |
| `+` (master grow) | `prefix + +` maximizes pane (zoom) | `}` |
| `-` (master shrink) | `prefix + -` splits vertically | `{` |
| `S` (sync) | `prefix + S` is commonly bound to sync-panes | `""` (disable) |
| `.` (rotate) | `prefix + .` moves pane to another window | `R` |
| `,` (flip) | `prefix + ,` renames window | `F` |
| `C-r` (circulate) | `prefix + C-r` is not commonly bound | `C-n` |
| `p` (pick layout) | `prefix + p` is previous-window | `P` |
### Layout Picker
Interactive fzf-based layout picker with ASCII diagram previews.
```
┌──────────────────────────────────────────────────────────────┐
│ Select layout: │
│ │ Dwindle Layout (4 panes) │
│ > dwindle │ ┌──────────┬──────────┐ │
│ spiral │ │ │ 2 │ │
│ grid │ │ 1 ├─────┬────┤ │
│ main-vertical │ │ │ 3 │ 4 │ │
│ main-horizontal │ └──────────┴─────┴────┘ │
│ main-center │ BSP cascade toward corner │
│ monocle │ │
│ deck │ │
│ │ │
│ Current: dwindle │
└──────────────────────────────────────────────────────────────┘
```
The picker shows ASCII diagrams in a preview panel on the right side. Each layout displays a representative configuration. The current layout is shown in the header.
Requirements: fzf >= 0.44.0.
### Layout Cycling
```
dwindle --> spiral --> grid
^ |
| main-vertical <--+
| |
| main-horizontal
| |
| main-center
| |
| monocle
| |
+--- deck +
```
### BSP Orientation Flags
A 4-character string controlling how the BSP tree cascades. Each character is one binary choice.
| Position | Values | Meaning |
|:---------|:-------|:--------|
| 1 | `t` / `b` | Top or bottom corner |
| 2 | `l` / `r` | Left or right corner |
| 3 | `h` / `v` | Horizontal or vertical first split |
| 4 | `c` / `s` | Corner (dwindle) or spiral trajectory |
Default: `brvc` (bottom-right, vertical, corner).
## CLI
The dispatcher at `src/tiling.sh` accepts direct commands for scripting and custom bindings.
```bash
# Layouts
./src/tiling.sh layout dwindle brvc
./src/tiling.sh layout spiral
./src/tiling.sh layout grid
./src/tiling.sh layout main-center
./src/tiling.sh layout main-vertical
./src/tiling.sh layout main-horizontal
./src/tiling.sh layout monocle
./src/tiling.sh layout deck
# Operations
./src/tiling.sh balance
./src/tiling.sh equalize
./src/tiling.sh rotate 180
./src/tiling.sh flip v
./src/tiling.sh promote
./src/tiling.sh circulate prev
./src/tiling.sh autosplit
./src/tiling.sh resize-master grow
./src/tiling.sh sync
./src/tiling.sh swap R
./src/tiling.sh swap-pick
./src/tiling.sh pick
./src/tiling.sh cycle next
./src/tiling.sh undo
# Features
./src/tiling.sh mark editor
./src/tiling.sh jump editor
./src/tiling.sh scratchpad htop
./src/tiling.sh preset save dev
./src/tiling.sh preset apply dev
./src/tiling.sh workspace 3
./src/tiling.sh move-to-workspace 5
./src/tiling.sh project
# Diagnostics
./src/tiling.sh info
./src/tiling.sh doctor
./src/tiling.sh validate fix
./src/tiling.sh restore-layouts
./src/tiling.sh help
```
## How It Works
The core BSP algorithm computes a tmux custom layout string mathematically, then applies it in a single `select-layout` call.
**Step 1: Build.** `_bsp_build()` recursively divides the window into a binary tree. At each depth, the orientation flags determine the split direction. At depth 0, the configurable `split_ratio` controls the first division. The output is a tmux layout string:
```
200x50,0,0{100x50,0,0,0,100x50,101,0[100x24,101,0,1,100x25,101,25{50x25,101,25,2,49x25,152,25,3}]}
```
**Step 2: Checksum.** `_layout_checksum()` computes the CRC-16 prefix that tmux requires.
**Step 3: Apply.** `select-layout ,` positions all panes in one call. For spiral layouts, `_bsp_fix_pane_order()` swaps panes to the correct BSP depth positions.
State is stored in tmux user options:
| Option | Scope | Purpose |
|:-------|:------|:--------|
| `@tiling_revamped_layout` | window | Current layout name |
| `@tiling_revamped_orientation` | window | BSP orientation flags |
| `@tiling_revamped_layout_history` | window | Undo stack (pipe-separated) |
| `@tiling_revamped_applying` | global | Recursion guard |
| `@tiling_revamped_mark` | pane | Mark name |
| `@tiling_revamped_marks` | global | Mark index |
Project structure
```
tmux-tiling-revamped.tmux # TPM entry point: keybindings, hooks, version gates
src/
tiling.sh # Command dispatcher with help text
lib/
layouts/
dwindle.sh # BSP dwindle + shared _apply_bsp_layout
spiral.sh # BSP spiral (delegates to dwindle)
grid.sh # Even grid via tmux tiled
main-center.sh # Balanced center pane with side columns
main-vertical.sh # Master left, stack right
main-horizontal.sh # Master top, stack bottom
monocle.sh # Zoom toggle
deck.sh # Full-height equal-width cards
operations/
balance.sh # Equalize sizes within topology
equalize.sh # Force even distribution
rotate.sh # Rotate orientation 90/180/270
flip.sh # Mirror horizontally or vertically
promote.sh # Swap focused pane with master
circulate.sh # Shift pane positions
autosplit.sh # Smart split along longest axis
focus-resize.sh # Golden ratio resize on focus
resize-master.sh # Grow or shrink master pane
sync.sh # Toggle synchronize-panes
swap-direction.sh # Swap with directional neighbor
swap-pick.sh # Swap with fzf-selected pane
pick-layout.sh # fzf layout picker with previews
undo-layout.sh # Layout history and undo
validate.sh # Layout metadata validation
info.sh # Current state display
doctor.sh # Environment health check
features/
marks.sh # Named pane labels with fzf jump
scratchpad.sh # Persistent popup sessions
presets.sh # Save and restore layout configs
cycle.sh # Step through layout list
workspaces.sh # i3-style window switching
project-launcher.sh # fzf project directory opener
resurrect.sh # tmux-resurrect layout restore
tmux/
tmux-ops.sh # Get/set tmux options
tmux-config.sh # Option helpers, reapply helper
utils/
constants.sh # Option names and defaults
error-logger.sh # Rotating log file
has-command.sh # Command existence check
pane-guard.sh # Minimum pane size checker
deprecation.sh # Option migration warnings
test/
helpers.bash # Mock tmux for unit tests
tmux_helpers.bash # Real tmux server for integration tests
integration.bats # 64 end-to-end scenarios
balance.bats # 48 balance invariant tests
lib/ # 40 unit test files mirroring src/lib/
```
## Development
| Command | Description |
|:--------|:------------|
| `make test` | Run the full bats suite |
| `make test-unit` | Run unit tests only |
| `make lint` | ShellCheck all shell files |
| `make clean` | Remove temp test artifacts |
| `bats --recursive test/` | Run all 528 tests recursively |
## License
[MIT](LICENSE)