Заголовок панели в Tmux

На моей локальной машине у меня одновременно запущено 3 экземпляра node.js. У каждого есть своя панель в окне tmux, называемая «серверами». Проблема в том, что не так просто понять, какой узел работает в какой панели, потому что их журналы похожи.

Что мне нужно, так это заголовок для каждой панели. Как я понял, сам tmux не имеет этой функции: у него есть только заголовки для окон, а не для панелей. Запуск отдельного сеанса tmux внутри каждой панели для каждого экземпляра node.js выглядит излишним.

Так есть ли какая-то небольшая программа, которая запускает команду, оборачивая ее вывод указанной строкой состояния?

заранее спасибо


person Andrey Lushnikov    schedule 17.03.2012    source источник
comment
tmux версии 2.3 поддерживает заголовки панелей, см. stackoverflow.com/a/37602055/266453   -  person Dennis G    schedule 07.10.2016


Ответы (9)


tmux поддерживает заголовки для отдельных панелей, но не предоставляет расположение для отображения этих заголовков.

Вы можете установить заголовок панели с помощью управляющей последовательности ESC ]2; … ESC \ (например, см. раздел Имена и заголовки на справочной странице tmux). Вы можете сделать это из оболочки следующим образом:

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

Заголовок каждой панели по умолчанию соответствует имени хоста системы. По умолчанию заголовок активной панели отображается справа от строки состояния tmux (глобальное значение переменной сеанса status-right по умолчанию равно "#22T" %H:%M %d-%b-%y, которое показывает 22 символа заголовка панели, время и Дата).

Таким образом, если вы удовлетворены возможностью видеть заголовок активной панели (т. е. готовы переключаться между панелями, чтобы увидеть заголовок неактивной панели), вы можете обойтись функциями по умолчанию. Просто отправьте соответствующую escape-последовательность, устанавливающую заголовок, перед запуском основной команды для каждой панели.


Если вам абсолютно необходима выделенная строка для отображения некоторой информации о каждой панели, то вложенные сеансы tmux могут быть не такими (ненужными) «излишними», как вы могли подумать на первый взгляд.

В общем случае, чтобы обеспечить ненарушенную строку состояния на каком-либо заданном терминале, вам понадобится полный (повторный) эмулятор терминала, который находится между исходным терминалом и новым терминалом (одним с одной строкой меньше). Такая (повторная) эмуляция необходима для преобразования управляющих последовательностей, отправляемых на внутренний терминал, и их преобразования для исходного терминала. Например, чтобы поддерживать строку состояния в нижней части внешнего терминала, команда

Перейти к последней строке.

отправленный на внутренний терминал, должен стать

Переход к предпоследней строке.

при переводе и отправке на внешний терминал. Аналогично, LF, отправленный на внутренний терминал, должен стать

Если курсор находится на предпоследней строке, прокрутите эту строку и все строки над ней вверх на одну строку, чтобы обеспечить четкую предпоследнюю строку (защитив строку состояния в последней строке). В противном случае отправьте LF.

во внешнем терминале.

Такие программы, как tmux и screen, являются как раз такими повторными эмуляторами терминала. Конечно, вокруг эмулятора терминала есть много других функций, но вам понадобится большой кусок кода эмуляции терминала только для того, чтобы предоставить надежную строку состояния.


Однако есть легкое решение, если

  1. ваши программы (экземпляры Node.js) имеют ограниченное взаимодействие терминала с панелями, в которых они работают (т. е. без позиционирования курсора), и
  2. вы не изменяете размер панелей во время работы ваших программ.

Как и многие эмуляторы терминала, tmux поддерживает команду управления терминалом «установить область прокрутки» в своих панелях. Вы можете использовать эту команду, чтобы ограничить область прокрутки верхними (или нижними) строками 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'

Сценарий также должен работать вне tmux, если терминал поддерживает и публикует свои возможности csr и cup terminfo.

person Chris Johnsen    schedule 18.03.2012
comment
ваш скрипт работает именно так, как я ожидал; единственный вопрос: что нужно гуглить, чтобы настроить цвет non_scroll_line? - person Andrey Lushnikov; 19.03.2012
comment
Может быть, «цвет фона переднего плана возможностей terminfo» (т.е. читайте о цвете на справочной странице terminfo). Вы можете использовать tput для включения соответствующих управляющих последовательностей в аргумент «содержимое строки». Для большинства терминалов вы можете сделать линию «голубой (6) и зеленый (3) на пурпурном (5)» с помощью no_scroll_line top "$(tput setaf 6; tput setab 5)Node: $(tput setaf 3)foo$(tput op)" node foo.js. setaf устанавливает передний план, setab устанавливает фон, op сбрасывает цвета терминала по умолчанию. Возможности цвета принимают значения от 0 до 7, 0–15, 0–87 или 0–255, в зависимости от эмуляции вашего терминала. - person Chris Johnsen; 19.03.2012
comment
Теперь мы выпустили pymux. При этом отображаются строки заголовка панели:github.com/jonathanslenders/pymux - person Jonathan Slenders; 08.01.2016
comment
Кажется, поведение заключается в том, что заголовок панели настроен на команду, запускаемую в оболочке. Таким образом, он не будет работать, если мы не запустим внутри один долгоживущий процесс (который также знает, как выводить escape-последовательность, устанавливающую заголовок). - person Steven Lu; 18.07.2016
comment
Что я хочу сделать, так это присвоить имя панели, чтобы ссылаться на нее программно и отправлять нажатия клавиш без ручного переключения на нее. Похоже, я могу обойти это, используя функцию отметки. - person Steven Lu; 18.07.2016
comment
Пожалуйста, взгляните на ответ ниже: stackoverflow.com/a/37602055/266453 tmux начиная с версии 2.3 поддерживает заголовки в границах панели. - person Dennis G; 07.10.2016

Эта функция была добавлена ​​в tmux в этой фиксации. В версии 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}"
person kevmitch    schedule 02.06.2016
comment
Это показывает номер панели и заголовок по умолчанию. Как изменить это мышление? - person adn; 21.07.2016
comment
Я не уверен насчет номеров панелей, но он отвечает как заголовок окна xterm для экранирования последовательностей. Например, в bash я установил PS1='[\e]0;\u@\h: \w\a]$ ', чтобы получить user@host: working dir/ - person kevmitch; 22.07.2016
comment
Насколько я понимаю, вы заранее задали эту последовательность. Но нет ярлыка или комбинации клавиш, которая их меняет. Итак, в tmux вам нужна какая-то команда вне tmux, чтобы изменить его. Правильно? Или внутри есть какая-то последовательность, которая может его обновить? - person adn; 22.07.2016
comment
Да, вы просто устанавливаете переменную в работающей оболочке, и она обновляется при отображении следующего приглашения. Мне кажется, что tmux немного схематичен и на самом деле обновляет его только тогда, когда вы переключаетесь на другую панель. - person kevmitch; 23.07.2016
comment
На самом деле вы можете использовать pane-border-format для установки пользовательской строки формата для отображения панели (обычный формат #{...}). Я отредактировал ваш ответ, чтобы включить это. - person Dennis G; 07.10.2016
comment
@adn просто замени pane_current_command на pane_current_path - person sstruct; 27.07.2020

Поскольку 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
person Eyal Levin    schedule 25.04.2019
comment
Знаете ли вы, есть ли способ предотвратить изменение названия tmux из-под вас? Например, если я устанавливаю заголовок панели, а затем что-то делаю в этой панели, например cd $HOME, заголовок изменяется на значение $HOME. (Я вижу это на tmux 2.8.) - person pdoherty926; 07.02.2020
comment
@ pdoherty926 Возможно, вы уже получили ответ, но посмотрите set-window-option automatic-rename off. - person noname; 07.06.2020
comment
У меня есть set-option -g allow-rename off в моем файле .tmux.conf. - person Eyal Levin; 07.06.2020
comment
Спасибо за предложения. В итоге я использовал pane-border-format и предоставленную пользователем переменную (я не уверен, есть ли официальное название для этой функции), чтобы управлять тем, что отображается. Вот пример. - person pdoherty926; 07.06.2020

Я работаю над строкой состояния панели для tmux - ticket. Мою ветку разработки можно найти здесь на github: https://github.com/jonathanslenders/tmux

Прямо сейчас это уже добавляет работающую команду rename-pane "title". Есть еще некоторые ошибки, и API будет улучшаться. Идея состоит в том, чтобы создать строку состояния для каждой панели, которая может иметь некоторое форматирование, например строку состояния сеанса. Как и остальная часть tmux, все должно стать скриптовым и настраиваемым. Когда он будет завершен и станет стабильным, он, вероятно, будет включен в официальный tmux.

person Jonathan Slenders    schedule 12.04.2013
comment
Пока вы там, можете ли вы сделать так, чтобы заголовок панели становился заголовком окна по умолчанию во время разрыва панели? - person djsadinoff; 27.12.2015
comment
Эта ветка никогда не была объединена в tmux. Но вместо этого я создал pymux с заголовком панели: github.com/jonathanslenders/pymux - person Jonathan Slenders; 08.01.2016
comment
Эта команда не работает и в последней сборке (commit a24260). - person adn; 21.07.2016

Я использую tmux версии 2.3, я думаю, что стиль рамки не поддерживается в предыдущих версиях. это то, что сработало для меня:

Для каждой панели установите заголовок:

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

Потом:

tmux set -g pane-border-format "#{pane_index} #T"
person OriG    schedule 24.01.2017
comment
По крайней мере, в tmux 2.6 вы можете изменить заголовок панели в tmux: select-pane -T "my title" делает это. Вы даже можете настроить привязку клавиш, поэтому вам просто нужно указать заголовок: bind-key T command-prompt -p "New title:" 'select-pane -T "%%"' - person lucasem; 07.02.2018
comment
@lucasem, может быть, я не следил за этой веткой, но это похоже на ответ. - person icicleking; 20.08.2018
comment
@lucasem Я не уверен на 100%, но я считаю, что ваш метод (который IMO является лучшим и самым простым во всей этой теме для последних версий tmux) работает, только если для параметра pane-border-status установлено что-то (top или bottom). - person cjauvin; 24.05.2020

Гифка стоит тысячи слов. (источник)

tmux-xpanes — это терминальный разделитель на основе tmux, который поддерживает отображение заголовка для каждой панели через новый добавлена ​​опция -t.

person navigaid    schedule 06.07.2018
comment
Гифка стоит тысячи слов, но если ссылка сгниет, она ничего не стоит. - person Fund Monica's Lawsuit; 13.06.2019
comment
TBH GIF больше сбивает с толку, чем помогает. Сумбурно и слишком быстро, так что замысел совершенно не ясен. Только сделав 2 скриншота, один после первой команды, другой после второй, измененной команды, я понял, что происходит. Не отрицать его из-за усилий, которые вы приложили к нему, и в то время это могло быть лучшим решением (если это было до версии 2.6) - person Daniel F; 09.02.2021
comment
Вау! Работает как часы. Большое спасибо! - person logbasex; 09.07.2021

Да есть такая команда: tmux. Дайте вашему сеансу имя, и оно будет отображаться во внутренней строке состояния:

TMUX=0 tmux new-session -s my-new-session
person event_jr    schedule 17.03.2012
comment
Да, спасибо за ответ! Но, таким образом, мне придется запускать новую сессию tmux в каждой панели только для одного заголовка в нижней части — это излишество, не так ли? - person Andrey Lushnikov; 18.03.2012
comment
Я не знаю. Это? Ты пробовал это? Сколько дополнительной памяти использует дополнительный сеанс? - person event_jr; 18.03.2012
comment
да, я использовал вложенные сеансы tmux до сегодняшнего дня. Я не уверен в потреблении памяти и тому подобных вещах - мне просто не нравится сама концепция, потому что она не чистая. - person Andrey Lushnikov; 19.03.2012

В краткосрочной перспективе это бесполезно, но есть запрос на функцию для заголовков для каждой панели в tmux: http://sourceforge.net/tracker/?func=detail&aid=3495916&group_id=200378&atid=973265#

Между тем, как уже упоминалось, вложение tmux работает прилично.

person Newtonx    schedule 19.10.2012

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

person sstruct    schedule 27.07.2020