Tmux中的窗格标题

时间:2012-03-17 06:46:09

标签: command-line title tmux pane

在我的本地计算机上,我有3个node.js实例同时运行。每个窗口都在一个名为“servers”的tmux窗口中拥有自己的窗格。问题是找出哪个节点在哪个窗格中运行并不容易,因为它们的日志类似。

我需要的是每个窗格的标题。正如我所知,tmux本身没有这个功能:它只有窗口的标题而不是窗格。在每个窗格内为每个node.js实例启动单独的tmux会话看起来像是一种过度杀伤。

是否有一些小程序启动命令,用指定的状态栏包装其输出?

提前致谢

9 个答案:

答案 0 :(得分:71)

tmux 支持每个窗格的标题,但它不提供显示这些标题的每个窗格位置。

您可以使用转义序列ESC ]2; ... ESC \设置窗格标题(例如,请参阅 tmux中名称和标题部分 manpage)。您可以从shell中执行此操作:

printf '\033]2;%s\033\\' 'title goes here'

每个窗格的标题默认为系统的主机名。默认情况下,活动窗格的标题显示在 tmux 状态行的右侧(会话变量status-right的默认全局值为"#22T" %H:%M %d-%b-%y,显示22个字符窗格的标题,时间和日期。

因此,只要您对能够看到活动窗格的标题(即愿意切换窗格以查看非活动窗格的标题)感到满意,您就可以使用默认功能。只需在为每个窗格启动main命令之前发送相应的标题设置转义序列。


如果你绝对需要专用的一行来显示一些每个窗格的信息,那么嵌套的 tmux 会话可能没有你想象的那么多(不必要)“过度杀伤”。

在一般情况下,要在某个给定终端上提供inviolate状态行,您需要一个位于原始终端和新终端(一个少一行)之间的完整终端(重新)仿真器。需要这种(重新)仿真来转换发送到内部终端的控制序列并将它们转换为原始终端。例如,要在外部终端的底部维护状态行,请执行命令

  

移到最后一行。

发送到内部终端必须成为

  

转到倒数第二行。

翻译并发送到外部终端时。同样,发送到内部终端的LF必须变为

  

如果光标位于倒数第二行,则滚动此行及其上方的所有行向上一行,以提供明确的倒数第二行(保护最后一行的状态行)。   否则,发送一个LF。

在外部终端。

tmux screen 等程序就是这样的终端重新模拟器。当然,终端仿真器周围还有许多其他功能,但您需要大量的终端仿真代码才能提供可靠的状态行。


然而,只要

,就有一个轻量级的解决方案
  1. 您的程序( Node.js 实例)与运行它们的窗格(即没有光标定位)的终端交互有限,并且
  2. 在程序运行时,不要调整窗格大小。
  3. 与许多终端仿真器一样, tmux 在其窗格中支持“set scrolling region”终端控制命令。您可以使用此命令将滚动区域限制为终端的顶部(或底部)N-1行,并将某种实例标识文本写入非滚动行。

    需要限制(不允许游标移动命令,不调整大小),因为生成输出的程序(例如 Node.js 实例)不知道滚动仅限于特定地区。如果输出生成程序碰巧将光标移动到滚动区域之外,则输出可能变为乱码。同样,当终端调整大小时,终端仿真器可能会自动重置滚动区域(因此“非滚动线”可能会最终向上滚动)。

    我编写了一个脚本,使用tput生成适当的控制序列,写入非滚动行,并在将光标移动到滚动区域后运行程序:

    #!/bin/sh
    
    # usage: no_scroll_line top|bottom 'non-scrolling line content' command to run with args
    #
    #     Set up a non-scrolling line at the top (or the bottom) of the
    #     terminal, write the given text into it, then (in the scrolling
    #     region) run the given command with its arguments. When the
    #     command has finished, pause with a prompt and reset the
    #     scrolling region.
    
    get_size() {
        set -- $(stty size)
        LINES=$1
        COLUMNS=$2
    }
    set_nonscrolling_line() {
        get_size
        case "$1" in
            t|to|top)
                non_scroll_line=0
                first_scrolling_line=1
                scroll_region="1 $(($LINES - 1))"
                ;;
            b|bo|bot|bott|botto|bottom)
                first_scrolling_line=0
                scroll_region="0 $(($LINES - 2))"
                non_scroll_line="$(($LINES - 1))"
                ;;
            *)
                echo 'error: first argument must be "top" or "bottom"'
                exit 1
                ;;
        esac
        clear
        tput csr $scroll_region
        tput cup "$non_scroll_line" 0
        printf %s "$2"
        tput cup "$first_scrolling_line" 0
    }
    reset_scrolling() {
        get_size
        clear
        tput csr 0 $(($LINES - 1))
    }
    
    # Set up the scrolling region and write into the non-scrolling line
    set_nonscrolling_line "$1" "$2"
    shift 2
    
    # Run something that writes into the scolling region
    "$@"
    ec=$?
    
    # Reset the scrolling region
    printf %s 'Press ENTER to reset scrolling (will clear screen)'
    read a_line
    reset_scrolling
    
    exit "$ec"
    

    您可以这样使用它:

    tmux split-window '/path/to/no_scroll_line bottom "Node instance foo" node foo.js'
    tmux split-window '/path/to/no_scroll_line bottom "Node instance bar" node bar.js'
    tmux split-window '/path/to/no_scroll_line bottom "Node instance quux" node quux.js'
    

    只要终端支持并发布其csrcup terminfo功能,该脚本也应该在 tmux 之外工作。

答案 1 :(得分:52)

此功能已添加到this commit中的tmux git中。它不是在2.2版本中,但看起来它将在2.3中。

启用它:

tmux set -g pane-border-status top

或者如果您愿意:

tmux set -g pane-border-status bottom

要将自定义文字设置为窗格边框状态行,您可以使用pane-border-format,例如像这样:

tmux set -g pane-border-format "#{pane_index} #{pane_current_command}"

答案 2 :(得分:14)

我正在处理tmux - ticket的窗格状态栏。 我的开发分支可以在github上找到: https://github.com/jonathanslenders/tmux

现在,这已经添加了一个有效的重命名窗格“标题”命令。仍然存在一些错误,API将会改进。我们的想法是为每个窗格创建一个状态栏,它可以有一些格式,例如会话状态栏。与tmux的其余部分一样,一切都应该是可编写脚本的,并且可以自定义。完成并稳定后,它可能会包含在官方tmux中。

答案 3 :(得分:10)

我使用的是tmux 2.3版,我认为以前的版本不支持边框样式。 这对我有用:

为每个窗格设置标题:

printf '\033]2;My Pane Title\033\\'

然后:

tmux set -g pane-border-format "#{pane_index} #T"

答案 4 :(得分:6)

是的,有这样一个命令:tmux。为您的会话命名,它将显示在内部状态栏中:

TMUX=0 tmux new-session -s my-new-session

答案 5 :(得分:6)

gif值一千字。 (source

tmux-xpanes是基于tmux的终端分配器,它支持 通过新添加的-t选项显示每个窗格的标题。

答案 6 :(得分:4)

这在短期内没有帮助,但tmux中有每个窗格标题的功能请求:http://sourceforge.net/tracker/?func=detail&aid=3495916&group_id=200378&atid=973265#

与此同时,正如其他人所提到的,嵌套tmux工作正常。

答案 7 :(得分:4)

tmux 2.6起,您可以执行以下操作:

$ tmux select-pane -t {pane} -T {title}

# Examples:
$ tmux select-pane -T title1          # Change title of current pane
$ tmux select-pane -t 1 -T title2     # Change title of pane 1 in current window
$ tmux select-pane -t 2.1 -T title3   # Change title of pane 1 in window 2

您可以在状态栏中看到每个窗格的标题,其中包括:

$ tmux set pane-border-status bottom      # For current window
$ tmux set -g pane-border-status bottom   # For all windows

通过以下方式禁用状态栏:

$ tmux set pane-border-status off       # For current window
$ tmux set -g pane-border-status off    # For all windows

答案 8 :(得分:0)

TL; DR

将以下配置添加到您的tmux配置文件(在我的情况下为~/.tmux.conf.local

# dispaly pane_current_path as the pane title
set -g pane-border-status top
set -g pane-border-format "#{pane_index} #{pane_current_path}"

然后运行:

tmux source-file ~/.tmux.con

享受

感谢https://stackoverflow.com/a/37602055/5121972