如何使 tmux 的窗格宽度固定?

hao*_*lee 5 tmux

假设我将一个窗口分成 2 个窗格,右侧窗格的宽度为 20 个单元格。但是当我调整外部终端模拟器的大小时,窗格的宽度会发生变化。

有没有什么办法解决这一问题?因为我想显示格式适合 20 个单元格的信息

sci*_*tor 4

据我所知,tmux 没有任何将宽度固定为最小值的设置,只有最大值。这是因为终端窗口的大小可以调整为小于 tmux 的最小值,而 tmux 可能没有合适的方法来处理此问题。

也就是说,如果您打开了其他 tmux 窗格,您可以向 PS1 ( PS1='$(resizePane $id)other-stuff') 或 PROMPT_COMMAND 添加一个小脚本,以便在使用 tmux 中的其他窗格时不断调整您希望保持 20c 宽度的信息窗格的大小。本质上,1) 您可以打开程序,2) 调整终端大小,3) 移动到另一个窗格,4) 键入Enter并单击,窗格就会调整大小。

您应该查看手册页

resize-pane [-DLRU] [-t target-pane] [adjustment]
Run Code Online (Sandbox Code Playgroud)

如果您位于所需的窗格中,则必须做的就是将宽度从左侧 -L 或右侧 -R 缩小 x 个字符,以达到 20。本质上,如果窗格靠墙更高与窗格相比,使用其方向进行缩小,使用相反的方向进行放大。如果我的窗格靠近右墙,请使用 -R 缩小宽度,使用 -L 放大宽度。

要获得正确数量的字符,您需要知道窗格的当前宽度,如果您键入,可以与窗格 ID 一起找到该宽度

tmux list-panes
Run Code Online (Sandbox Code Playgroud)

我还不确定有什么方法可以告诉您当前所在的窗格编号,除非通过Prefix+q或键入

tmux display-panes
Run Code Online (Sandbox Code Playgroud)

这将为我们提供当前窗口中所有窗格的 ID 号。如果我们知道 id# ($id),假设它靠右墙,我们可以通过以下方式将窗格大小调整为 20 个字符宽:

paneWidths=$(tmux list-panes | awk '{print $2}' | cut -c 2- | cut -f 1 -d'x')
currentWidth=$(echo $paneWidths | sed $id'q;d')
resizeNum=$(expr $currentWidth - 20)

tmux resize-pane -R -t $id $resizeNum
Run Code Online (Sandbox Code Playgroud)

请注意,resizeNum 不能为负数。如果为负数,则使用另一侧将大小调整为 resizeNum 的绝对值(这可以自动化,但我将由您决定)。另外,如果您将其合并到程序的代码中,您可以忽略“-t $id”部分,但我不知道如何从程序中自动查找 $id 。

您也可以查看tmux setw main-pane-width tmux setw other-pane-width,如果您重新加载新的图块格式,它将设置特定的窗格宽度。循环格式使用Prefix+space

希望这可以帮助!

--- 编辑以添加有关自动化的更多信息 ---

我之前的想法是,您可以转到一个新窗格并运行PS1="$(resizePane $id)${PS1}",然后ENTER在另一个窗格中单击,以便您可以继续在新调整大小的窗格中工作,但我考虑了一个可能适合您的新选项......

自从最初发布以来,我重新考虑了这个想法,并且我认为如果运行的程序有一个可以发送 shell 命令的循环,那么它可以合理地实现自动化。这是因为我们可以通过本质上分割窗口来运行程序。这是我的意思的一个例子。下面的代码

  1. 用户运行runCodeSplit.sh,其中
  2. 在最终窗格的右侧水平分割一个新窗格(20c 宽度)并运行test.sh
  3. 进入循环
  4. 检查当前窗格大小并尝试调整大小
  5. 休眠 10 秒(但您可以更改此设置以执行您想要的任何操作)
  6. 重复 3 和 4 10 次,然后退出

runCodeSplit.sh:

#!/bin/bash
# runCodeSplit.sh

paneID=$(tmux list-panes | wc -l)
echo "pane: $paneID"
echo $(expr $paneID - 1)

# now, open a new pane and run the func
tmux split-window -h -l 20 -t $(expr $paneID - 1 ) "~/test.sh $paneID"
Run Code Online (Sandbox Code Playgroud)

测试.sh:

#!/bin/bash
# test.sh
if [[ $# -lt 1 ]] ; then 
    echo "please provide the pane-number" 
    exit 
fi
paneID=$1
i=0
while [[ i -lt 10 ]] ; do
    # find the current width and resize it at every loop
    width=$(tmux list-panes | awk '{print $2}' | cut -c 2- | cut -f 1 -d'x' | sed $(expr $paneID + 1)'q;d')
    resizeNum=$(expr $width - 20)
    echo "$paneID : w $width     r $resizeNum"

    if [[ $resizeNum -gt 0 ]] ; then
        tmux resize-pane -R -t $paneID $resizeNum
    elif [[ $resizeNum -lt 0 ]] ; then
        tmux resize-pane -L -t $paneID $(expr 0 - $resizeNum)
    fi 

    #now, we can do stuff ... 
    let i++
    echo "i= $i / 10"
    sleep 10
done
read -p "Press any key to close this pane ... " -n1 -s
Run Code Online (Sandbox Code Playgroud)

注意:不幸的是,按照我上面实现的方式,您应该只在每个 tmux 窗口运行一次。问题是,每次运行它时,它们都会聚集在一起,这反过来又会使它们争夺空间(一个会缩小另一个以扩展,反之亦然)。您也许可以解决这个问题,但我将其留给您自己解决。