aboutsummaryrefslogtreecommitdiff
path: root/README
diff options
context:
space:
mode:
authorLena <lena@omega>2026-07-01 00:00:00 +0000
committerLena <lena@omega>2026-07-01 00:00:00 +0000
commit3b6025fc0ad913163e3b85d6aad5fe0a3d094a82 (patch)
tree6b3a2ec34c621eed458e3fd39e1caadcbe817426 /README
downloadtilemux-3b6025fc0ad913163e3b85d6aad5fe0a3d094a82.tar.gz
Enter tilemuxHEADmaster
An i3-like tiling layer for tmux in a single config file. No plugins, no helper scripts, no dependencies. Design target is tmux 3.6. Windows are workspaces and panes are tiles. tmux exposes only pane geometry to its formats, so the bindings work to one explicit model instead: a window is a row of columns, each column a stack of panes. Every binding is on Alt, so no prefix is needed. README covers install, the model, debugging and the caveats.
Diffstat (limited to 'README')
-rw-r--r--README137
1 files changed, 137 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..b4cb829
--- /dev/null
+++ b/README
@@ -0,0 +1,137 @@
+tilemux
+=======
+An i3-like tiling layer for tmux, in a single config file. No plugins, no
+helper scripts, no dependencies. Design target is tmux 3.6.
+
+Windows are workspaces, panes are tiles, and every binding is on Alt so
+no prefix is needed. Ctrl+Space is kept as the tmux prefix so nothing is
+out of reach.
+
+
+Install
+-------
+ cp tilemux.conf ~/.tilemux.conf
+
+Then add an alias to your shell rc:
+
+ alias tilemux='tmux -L tilemux -f ~/.tilemux.conf'
+
+ tilemux new -A -s main start it, or attach if already running
+ tilemux ls list sessions
+ tilemux kill-server stop it
+
+tilemux runs on its own socket, so it has its own server and its own
+sessions and the tmux you already use is untouched. The socket is what
+does the isolating: -f is read only when a server starts, so on its own
+it would be ignored by an already running tmux.
+
+Alt+? lists every key. The rules are commented in tilemux.conf next to
+the bindings that implement them, so this file only shows what they do.
+
+
+The model
+---------
+tmux keeps a layout as a tree but exposes only pane geometry to its
+formats, so the bindings work to one explicit model instead:
+
+ a window is a row of columns, and each column is a stack of panes
+
+Alt+Shift+Left/Right moves a pane between columns. It leaves its own
+column and joins the neighbouring one:
+
+ +----+----+ +----+----+
+ | a | C | | | a |
+ +----+----+ -> | +----+
+ | B | D | | B | C |
+ +----+----+ | +----+
+ | | D |
+ +----+----+
+
+Alt+Shift+Up/Down reorders a pane inside the column it is already in:
+
+ +----+----+ +----+----+
+ | a | C | | B | C |
+ +----+----+ -> +----+----+
+ | B | D | | a | D |
+ +----+----+ +----+----+
+
+At the edge of the window there is no neighbour to move to, so the pane
+leaves its column and becomes a column of its own, or a full-width row
+going up or down. This is how a layout is restructured without presets:
+
+ +----+----+ +--+--+----+
+ | A | C | |A | | |
+ +----+----+ -> +--+ C| d |
+ | B | d | |B | | |
+ +----+----+ +--+--+----+
+
+Alt+m and a direction is the way back in. Moving pushes panes apart, and
+a pane that is a whole column swaps with its neighbours instead of
+joining them, so merging needs a key of its own:
+
+ +---+---+---+ +---+-------+
+ | | | | | | B |
+ | A | B | c | -> | A +-------+
+ | | | | | | c |
+ +---+---+---+ +---+-------+
+
+
+Debugging
+---------
+Reload, then look at what a key runs and what the rules are reading:
+
+ tilemux source-file ~/.tilemux.conf
+ tilemux list-keys -T root | grep 'M-L'
+ tilemux display -p '#{window_layout}'
+ tilemux list-panes -F '#{pane_index} #{pane_left},#{pane_top}'
+
+Watch for #{>:a,b}: it compares strings. Numbers need #{e|>:a,b}.
+
+To try a binding without disturbing the tmux you work in, run a second
+server on its own socket and attach to it from a pane of the first.
+send-keys writes to that pane, so the attached client reads the keys and
+the binding fires:
+
+ tmux -L test -f ./tilemux.conf new-session -d -s w -x 200 -y 48
+ tmux -L ctl -f /dev/null new-session -d -x 200 -y 49 \
+ 'tmux -L test attach -t w'
+ tmux -L test split-window -h
+ tmux -L test select-pane -t 1
+ tmux -L ctl send-keys -t 0 M-L
+ tmux -L test list-panes -F '#{pane_index} #{pane_left} #{pane_active}'
+ tmux -L test kill-server
+
+Killing the test server ends the attach, and the ctl server with it.
+
+
+Caveats
+-------
+A 2x2 built as columns of rows and one built as rows of columns look
+identical on screen. Geometry cannot tell them apart, so both behave as
+columns of rows.
+
+A pane that spans the window swaps with a neighbour instead of pushing
+past it, and tmux picks which neighbour by geometry, so a full-height
+column can trade places with one pane of the stack beside it. Alt+m
+puts it back.
+
+A pane leaving a stack does not make the rest rebalance; the neighbour
+absorbs the space, as it does when a pane is killed. Alt+r then = evens
+a container out.
+
+Copy mode has its own key table. With the default emacs mode-keys it
+takes seventeen of these keys for itself: Alt+1 to Alt+9, Alt+Up,
+Alt+Down, Alt+b, Alt+f, Alt+l, Alt+m, Alt+r and Alt+v. Those do not
+reach tilemux while a pane is in copy mode, and every other key falls
+through and works. setw -g mode-keys vi avoids the clash entirely.
+
+Alt+? needs a terminal of at least 76x23. Below that tmux refuses the
+popup and says so in the status line; there is no smaller help.
+
+Alt+Shift with a number assumes the shifted symbols of a US layout
+(!@#$%^&*()).
+
+
+License
+-------
+BSD 3-Clause. See LICENSE.