Ответ 1
tmux поддерживает заголовки для каждой панели, но не отображает местоположение каждой панели для отображения этих заголовков.
Вы можете установить заголовок панели с escape-последовательностью ESC ]2;
... ESC \
(например, см. раздел "Названия и заголовки" в man-странице tmux). Вы можете сделать это из оболочки следующим образом:
printf '\033]2;%s\033\\' 'title goes here'
Каждый заголовок по умолчанию имеет имя системного хоста. По умолчанию заголовок активных панелей отображается в правой части строки состояния tmux (глобальное значение по умолчанию для переменной сеанса status-right
равно "#22T" %H:%M %d-%b-%y
, которое показывает 22 символа названия панелей, времени и даты).
Итак, до тех пор, пока вы удовлетворены тем, что можете видеть заголовок активных панелей (то есть, желая переключить панели, чтобы увидеть заголовок неактивной области), вы можете использовать функции по умолчанию. Просто отправьте соответствующую управляющую последовательность заголовка перед началом основной команды для каждой панели.
Если вам абсолютно нужна выделенная строка для отображения какой-либо информации на панели, тогда вложенные сеансы tmux могут быть не такими (ненужными) "излишествами", как вы могли бы подумать.
В общем случае для предоставления строки неприкосновенного состояния на каком-то данном терминале вам понадобится полный эмулятор терминала (re), который находится между исходным терминалом и новым терминалом (один с одним меньшим количеством строк). Такая (повторная) эмуляция необходима для перевода управляющих последовательностей, отправленных на внутренний терминал, и перевода их для исходного терминала. Например, чтобы поддерживать линию состояния в нижней части внешнего терминала, команда
Переход к последней строке.
отправленный на внутренний терминал, должен стать
Переместитесь к следующей строке.
при переводе и отправке на внешний терминал. Аналогично, LF, отправленный на внутренний терминал, должен стать
Если курсор находится рядом с последней строкой, прокрутите эту строку и все строки над ней на одну строку, чтобы обеспечить четкую следующую строку (защита строки состояния на последней строке). В противном случае отправьте LF.
во внешнем терминале.
Такие программы, как tmux и screen, являются именно такими терминальными эмуляторами. Конечно, есть много других функций, обернутых вокруг эмулятора терминала, но для обеспечения надежной строки состояния вам понадобится большой фрагмент кода эмуляции терминала.
Однако существует легкое решение, если
- ваши программы (Node.js экземпляры) имеют ограниченные взаимодействия с терминалами, в которых они работают (то есть без позиционирования курсора), и
- вы не изменяете размер панелей во время работы своих программ.
Как и многие терминальные эмуляторы, tmux поддерживает команду управления терминацией "set scrolling" в своих панелях. Вы можете использовать эту команду, чтобы ограничить область прокрутки верхними (или нижними) линиями N-1 терминала и записать какой-то экземпляр, идентифицирующий экземпляр, в строку без прокрутки.
Ограничения (нет допустимых команд перемещения курсора, без изменения размера), потому что программа, которая генерирует результат (например, a Node.js), не знает, что прокрутка ограничена определенным регионом. Если программа, генерирующая выходные данные, переместила курсор за пределы области прокрутки, тогда выход может исказиться. Аналогично, эмулятор терминала, вероятно, автоматически сбрасывает область прокрутки при изменении размера терминала (так что, вероятно, прокрутка прокрутки будет завершена).
Я написал script, который использует 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
"[email protected]"
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'
script также должен работать вне tmux, пока терминал поддерживает и публикует возможности csr
и cup
terminfo.