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


88

На моїй локальній машині у мене є 3 екземпляри node.js, що працюють одночасно. Кожна з них має власну область у вікні tmux, яка називається "сервери". Проблема в тому, що не так просто зрозуміти, який вузол запущений в якій області, оскільки їх журнали схожі.

Мені потрібен заголовок для кожної панелі. Як я зрозумів, сам tmux не має цієї функції: він має лише заголовки для вікон, а не для панелей. Запуск окремого сеансу tmux всередині кожної області для кожного екземпляра node.js виглядає як надмірне.

То чи існує якась невеличка програма, яка запускає команду, обгортаючи її вихідні дані заданим рядком стану?

Спасибі заздалегідь


1
tmux станом на версію 2.3 підтримує заголовки панелей, див. stackoverflow.com/a/37602055/266453
Денніс Г

Відповіді:


80

tmux підтримує заголовки на окремі панелі, але не забезпечує розташування на панелі для відображення цих заголовків.

Ви можете встановити заголовок панелі за допомогою екрануючої послідовності ESC ]2;... ESC \(наприклад, див. Розділ " Імена та заголовки" на сторінці сторінки tmux ). Ви можете зробити це з оболонки так:

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

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

Отже, поки ви задоволені можливістю побачити заголовок активної панелі (тобто бажаєте переключити панелі, щоб побачити заголовок неактивної панелі), ви можете обійтись функціоналом за замовчуванням. Просто надішліть відповідну послідовність екранів для встановлення заголовка, перш ніж запускати головну команду для кожної панелі.


Якщо вам абсолютно потрібен виділений рядок для відображення певної інформації на окремій панелі, то вкладені сеанси 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та cupterminfo можливості.


ваш сценарій працює точно так, як я очікував; єдине питання: що мені потрібно гуглити, щоб налаштувати колір "non_scroll_line"?
Андрій Лушніков

1
Можливо, “колір фону переднього плану можливості 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, залежно від вашої емуляції терміналу.
Кріс Джонсен,

Тепер ми випустили pymux. Тут відображаються рядки заголовків панелі: github.com/jonathanslenders/pymux
Джонатан Слендерс

Здається, поведінка полягає в тому, що для заголовка панелі встановлено команду, яка запускається в оболонці. Отже, він не буде «прилипати», якщо ми не запустимо один довгоживучий процес (який також знає, як вивести послідовність екрану для встановлення заголовка) всередині.
Стівен Лу

4
Будь ласка , зверніть увагу на відповідь нижче: stackoverflow.com/a/37602055/266453 tmux в версії 2.3 підтримують назви в склопакетах кордонів.
Dennis G

78

Ця функціональність була додана до 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}"

1
Це показує номер панелі та типовий заголовок. Як ви можете змінити це думка?
адд.

Я не впевнений у номерах панелей, але це відповідає як заголовок вікна xterm, щоб уникнути послідовностей. Наприклад, за допомогою bash я встановив PS1 = '[\ e] 0; \ u @ \ h: \ w \ a] $', щоб отримати "user @ host: working dir /"
kevmitch

Наскільки я розумію, ви встановили цю послідовність наперед. Але не існує комбінації клавіш або комбінації клавіш, які б їх змінювали. Отже, tmuxвам потрібна якась зовнішня команда tmuxдля її зміни. Правда? Або всередині є якась послідовність, яка може її оновити?
ADN

Так, ви просто встановили змінну в запущеній оболонці, і вона оновлюється, коли буде намальовано наступний запит. Для мене здається, що tmux трохи схематичний і насправді оновлює його лише при переході на іншу панель.
kevmitch

Ви насправді можете використовувати pane-border-formatдля встановлення користувацького рядка формату для відображення панелі (звичайний #{...}формат). Я відредагував вашу відповідь, щоб включити це.
Dennis G

32

Оскільки 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

Чи знаєте ви, чи є спосіб запобігти tmux змінювати заголовок з-під вас? Наприклад, якщо я встановив заголовок панелі, а потім зробив щось на цій панелі, наприклад cd $HOME, заголовок змінився на значення $HOME. (Я бачу це на tmux 2.8.)
pdoherty926

1
@ pdoherty926 Можливо, ви вже отримали відповідь, але перевірте set-window-option automatic-rename off.
noname

Я маю set-option -g allow-rename offу своєму .tmux.confфайлі.
Еял Левін,

1
Дякую за пропозиції. Я завершив використання pane-border-formatта надану користувачем змінну (я не впевнений, чи існує офіційна назва цієї функції) для управління тим, що відображається. Ось приклад.
pdoherty926

14

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

Зараз це вже додає працюючу команду "title" на панелі перейменування . Ще є деякі помилки, і API покращиться. Ідея полягає в тому, щоб створити рядок стану на кожну панель, яка може мати певне форматування, наприклад рядок стану сеансу. Як і решта tmux, все повинно стати сценарійним та настроюваним. Після завершення роботи та стабільності, можливо, він буде включений в офіційний tmux.


Поки ви там, чи можете ви зробити так, щоб заголовок панелі став титулом вікна за замовчуванням під час розбиття панелі?
djsadinoff

Цю гілку ніколи не об'єднували в tmux. Але я натомість створив pymux, який має рядки заголовків панелі: github.com/jonathanslenders/pymux
Джонатан Слендерс

Ця команда також не працює в останній збірці (коміт a24260).
ад

14

Я використовую tmux версії 2.3, я думаю, стиль кордону не підтримується в попередніх версіях. ось що мені вдалося:

Для кожної області встановіть заголовок:

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

Тоді:

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

9
Принаймні так само недавно, як tmux 2.6, ви можете змінити заголовок панелі в межах tmux: select-pane -T "my title"робить це. Ви навіть можете налаштувати прив'язку ключів, тому вам просто потрібно вказати заголовок:bind-key T command-prompt -p "New title:" 'select-pane -T "%%"'
lucasem

3
@lucasem, можливо, я не стежив за цією темою, але це схоже на відповідь.
icicleking

@lucasem Я не впевнений на 100%, але я вважаю, що ваш метод (який IMO є найкращим і найпростішим у всій цій темі, для останніх версій tmux) працює лише в тому випадку, якщо для pane-border-statusпараметра встановлено щось ( topабо bottom).
cjauvin

11

GIF коштує тисячі слів. ( джерело )

tmux-xpanes - це роздільник терміналів на основі tmux, який підтримує відображення заголовка для кожної області за допомогою нещодавно доданої -tопції.


1
GIF коштує тисячі слів, але якщо він коли-небудь посилається, він нічого не гниє.
Позов до Моніки

7

Так , є така команда: tmux. Дайте своїй сесії назву, і вона відобразиться у внутрішньому рядку стану:

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

2
Так, дякую за вашу відповідь! Але, отже, мені доведеться запустити новий сеанс tmux на кожній панелі лише для одного заголовка внизу - це щось надмірно, чи не так?
Андрій Лушніков,

Не знаю. Є це? Ви пробували? Скільки зайвої пам’яті використовується додатковий сеанс?
event_jr

так, я використовував вкладені сеанси tmux до сьогодні. Я не впевнений у споживанні пам'яті та подібних речах - мені просто не подобається сама концепція, оскільки вона не чиста.
Андрій Лушніков


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.