I wrote the below script to easily place panes in a grid. It uses a function from Sleep_Walker's blog. It's unclear to me what the licence is. To be on the safe side I removed the function from my code and posted it separately as a proper citation.
You need to compose the full script by pasting the function into the script.
#!/bin/bash
# number of rows
m="$2"
# number of columns
n="$1"
target="${3:-$TMUX_PANE}"
set -- $(tmux list-panes -t "$target" -F '#{pane_id}')
n="${n:-$(($#/m))}"
m="${m:-$(($#/n))}"
if [ "$#" -ne "$((m*n))" ]; then
printf '%s: panes needed for %sx%s layout: %s; panes detected: %s. Aborting.\n' "$0" "$n" "$m" "$((m*n))" "$#" >&2
exit 1
fi
if [ "$m" -eq 1 ]; then
layout=even-horizontal
elif [ "$n" -eq 1 ]; then
layout=even-vertical
else
# ---------- IMPORTANT ----------
# Visit http://sleepwalker-hnd.blogspot.com/2016/07/tmux-layout-checksum.html
# and paste tmux_layout_checksum function here.
create_row() {
row="${n}x1,0,${1}{"
shift
for j in $(seq 0 "$((n-1))"); do
row="${row}1x1,${j},0,${1#%},"
shift
done
row="${row%,}},"
}
layout="${n}x${m},0,0["
for i in $(seq 0 "$((m-1))"); do
create_row "$i" "$@"
shift "$n"
layout="${layout}${row}"
done
layout="${layout%,}]"
layout="$(tmux_layout_checksum "$layout"),${layout}"
fi
tmux select-layout -t "$target" "$layout"
The mentioned function:
tmux_layout_checksum() {
local layout="$1"
local csum=0
local i
for i in $(seq 0 $((${#layout} - 1))); do
let csum=$(((csum >> 1) + ((csum & 1) << 15)))
let csum=$((csum + $(LC_CTYPE=C printf '%d' "'${layout:$i:1}")))
done
printf '%x' "$((csum & 0xffff))"
}
Source: Sleep_Walker's blog.
Usage
Let's assume you named the script tmux-grid
. The usage is:
tmux-grid columns [rows [target]]
target
is exactly what tmux … -t
expects. With it you can target any tmux window. If omitted or empty, $TMUX_PANE
will be used. This way you don't need target
to change the layout of the current window from within the window itself.
rows
is the desired number of rows. If omitted or empty, the script will try to calculate this number from the number of existing panes and specified columns
.
columns
is the desired number of columns. If empty, the script will try to calculate this number from the number of existing panes and specified rows
.
In your case invoke one of these from within one of the 6 panes in question:
tmux-grid 3 # exactly 3 columns
tmux-grid '' 2 # exactly 2 rows
tmux-grid 3 2 # exactly 3 columns and exactly 2 rows
Note in general tmux-grid 2
needs an even number of panes; tmux-grid 3
needs the number to be divisible by 3; tmux-grid 3 2
needs exactly 6 panes.
If each pane is busy, you can invoke the command from another window. In this case you need to specify target
. This may be handy:
tmux-grid 3 '' {marked}
(For users not familiar with the concept of marked pane: this another answer of mine.)
How it works
The script builds a layout of panes of the size 1x1 each. Thanks to the fact tmux select-layout
recalculates the layout to match the window size, the panes are resized automatically.
Note: my later tests succeeded with panes of the size 0x0. I kept the original script though.
top
in the case that I'm able to drop a pane.