我在 tmux 窗口中打开了 6 个窗格。
Prefix:select-layout tiled
将它们排列如下:
+---------+---------+
| 1 | 2 |
+---------+---------+
| 3 | 4 |
+---------+---------+
| 5 | 6 |
+---------+---------+
这很好,但是我的显示器又宽又短,对于我正在运行的进程来说,这浪费了大量的水平空间。
我更愿意这样安排它们:
+-----+-----+-----+
| 1 | 2 | 3 |
+-----+-----+-----+
| 4 | 5 | 6 |
+-----+-----+-----+
假设窗格本身的数字顺序并不重要,并且关键的是不会停止任何正在运行的进程,我如何从第一个布局切换到第二个布局?
答案1
您可以使用tmuxlayout这是一个 perl 脚本,您只需在另一个窗口中运行它,tmuxlayout 123 456
它就会将适当的命令发送到正在运行的 tmux。
安装起来可能会有点困难,因为它可能不在您的发行版的存储库中。
如果您想tmuxlayout
在本地安装,无需成为 root 或弄乱您的/usr/lib
等等,您可以在安装cpan
命令后执行此操作,该命令应该在您的存储库中。
然后,您可以cpan
像下面这样以交互方式运行,只需输入 3 行。它将在您的$HOME
:perl5/
和中仅创建 2 个目录.cpan
。
下面我删除了大量的输出,因此当要求自动配置时只需按回车键yes
,当要求选择时按回车键local::lib
,然后输入命令install Term::Tmux::Layout
。
$ cpan
Would you like to configure as much as possible automatically? [yes]
What approach do you want? (Choose 'local::lib', 'sudo' or 'manual')
[local::lib]
cpan[1]> install Term::Tmux::Layout
如果它说安装正确,请在下一个提示符下输入 control-D 退出,并记下它要求您设置的值:
cpan[2]> ^D
*** Remember to add these environment variables to your shell config
and restart your shell before running cpan again ***
PATH="/home/meuh/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/meuh/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/meuh/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/meuh/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/meuh/perl5"; export PERL_MM_OPT;
使用上述 5 行创建一个小的 shell 脚本,并在末尾添加
tmuxlayout 123 456
并运行脚本。
答案2
我编写了以下脚本,以便轻松地将窗格放置在网格中。它使用来自Sleep_Walker 的博客。我不清楚许可证是什么。为了安全起见,我从代码中删除了该函数,并将其作为正确引用单独发布。
您需要通过将函数粘贴到脚本中来编写完整的脚本。
#!/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"
所提到的函数:
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))" }
来源:Sleep_Walker 的博客。
用法
假设你将脚本命名为tmux-grid
。用法如下:
tmux-grid columns [rows [target]]
target
正是所tmux … -t
期望的。有了它,您可以定位任何 tmux 窗口。如果省略或为空,$TMUX_PANE
则将被使用。这样,您无需target
从窗口本身内部更改当前窗口的布局。
rows
是所需的行数。如果省略或为空,脚本将尝试根据现有窗格的数量和指定的 来计算此数字columns
。
columns
是所需的列数。如果为空,脚本将尝试根据现有窗格的数量和指定的 来计算此数字rows
。
在您的情况下,从相关的6个窗格之一中调用其中一个:
tmux-grid 3 # exactly 3 columns
tmux-grid '' 2 # exactly 2 rows
tmux-grid 3 2 # exactly 3 columns and exactly 2 rows
注意一般tmux-grid 2
需要偶数个窗格;tmux-grid 3
需要数字可以被 3 整除;tmux-grid 3 2
需要恰好 6 个窗格。
如果每个窗格都很忙,您可以从另一个窗口调用该命令。在这种情况下,您需要指定target
。这可能很方便:
tmux-grid 3 '' {marked}
(对于不熟悉标记窗格概念的用户:这是我的另一个答案。
怎么运行的
该脚本构建了每个尺寸为 1x1 的窗格布局。由于重新tmux select-layout
计算布局以匹配窗口大小,因此窗格会自动调整大小。
注意:我后来的测试在大小为 0x0 的窗格上成功了。但我保留了原始脚本。