Titolo riquadro in Tmux


89

Sulla mia macchina locale ho 3 istanze di node.js in esecuzione simultaneamente. Ognuno ha il proprio pannello in una finestra di tmux chiamata "server". Il problema è che non è così facile capire quale nodo è in esecuzione in quale riquadro, perché i loro log sono simili.

Quello di cui ho bisogno è un titolo per ogni riquadro. Come ho capito, tmux stesso non ha la funzione: ha solo titoli per Windows e non per i riquadri. L'avvio di una sessione tmux separata all'interno di ogni riquadro per ogni istanza node.js sembra eccessivo.

Quindi c'è qualche piccolo programma che lancia un comando, avvolgendo il suo output con una barra di stato specificata?

Grazie in anticipo


1
tmux a partire dalla versione 2.3 supporta i titoli del riquadro, vedere stackoverflow.com/a/37602055/266453
Dennis G

Risposte:


80

tmux supporta i titoli per riquadro, ma non fornisce una posizione per riquadro per visualizzare questi titoli.

È possibile impostare il titolo di un riquadro con la sequenza di escape ESC ]2;… ESC \(ad esempio, vedere la sezione chiamata Nomi e titoli nella manpage di tmux ). Puoi farlo dalla shell in questo modo:

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

Il titolo di ogni riquadro è predefinito sul nome host del sistema. Per impostazione predefinita, il titolo del riquadro attivo viene visualizzato sul lato destro della riga di stato di tmux (il valore globale predefinito della variabile di sessione status-rightè "#22T" %H:%M %d-%b-%y, che mostra 22 caratteri del titolo del riquadro, l'ora e la data).

Quindi, fintanto che sei soddisfatto di essere in grado di vedere il titolo del riquadro attivo (cioè disposto a cambiare riquadro per vedere il titolo di un riquadro inattivo), puoi cavartela con la funzionalità predefinita. È sufficiente inviare la sequenza di escape dell'impostazione del titolo appropriata prima di avviare il comando principale per ogni riquadro.


Se hai assolutamente bisogno di una riga dedicata per visualizzare alcune informazioni per riquadro, le sessioni tmux annidate potrebbero non essere così (non necessarie) "eccessive" come potresti pensare.

Nel caso generale, per fornire una linea di stato inviolata su un determinato terminale, avrai bisogno di un (ri) emulatore di terminale completo che si trovi tra il terminale originale e un nuovo terminale (uno con una riga in meno). Tale (ri) emulazione è necessaria per tradurre le sequenze di controllo inviate al terminale interno e tradurle per il terminale originale. Ad esempio, per mantenere una riga di stato nella parte inferiore del terminale esterno, il comando

Passa all'ultima riga.

inviato al terminale interno deve essere diventato

Passa alla penultima riga.

quando tradotto e inviato al terminale esterno. Allo stesso modo, un LF inviato al terminale interno deve diventare

Se il cursore si trova sulla penultima riga, scorrere questa riga e tutte le righe sopra di essa di una riga, per fornire una riga chiara dal penultimo (proteggendo la riga di stato sull'ultima riga). Altrimenti, invia un LF.

nel terminale esterno.

Programmi come tmux e screen sono proprio questi re-emulatori di terminale. Certo, ci sono molte altre funzionalità avvolte attorno all'emulatore di terminale, ma avresti bisogno di una grande porzione di codice di emulazione di terminale solo per fornire una riga di stato affidabile .


Esiste, tuttavia, una soluzione leggera finché

  1. i tuoi programmi ( istanze Node.js ) hanno interazioni terminali limitate con i riquadri in cui sono in esecuzione (cioè nessun posizionamento del cursore), e
  2. non ridimensionare i riquadri mentre i programmi sono in esecuzione.

Come molti emulatori di terminale, tmux supporta un comando di controllo del terminale "set scrolling region" nei suoi riquadri. È possibile utilizzare questo comando per limitare l'area di scorrimento alle righe N-1 superiori (o inferiori) del terminale e scrivere una sorta di testo identificativo dell'istanza nella riga non scorrevole.

Le restrizioni (nessun comando di spostamento del cursore consentito, nessun ridimensionamento) sono richieste perché il programma che genera l'output (ad esempio un'istanza di Node.js ) non ha idea che lo scorrimento sia stato limitato a una particolare regione. Se il programma di generazione dell'output ha spostato il cursore al di fuori dell'area di scorrimento, l'output potrebbe diventare confuso. Allo stesso modo, l'emulatore di terminale probabilmente ripristina automaticamente la regione di scorrimento quando il terminale viene ridimensionato (quindi la "linea non scorrevole" finirà probabilmente per scorrere via).

Ho scritto uno script che utilizza tputper generare le sequenze di controllo appropriate, scrivere nella riga non a scorrimento ed eseguire un programma dopo aver spostato il cursore nella regione di scorrimento:

#!/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"

Potresti usarlo in questo modo:

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'

Lo script dovrebbe funzionare anche al di fuori di tmux fintanto che il terminale supporta e pubblica le sue capacità csre cupterminfo.


il tuo script funziona esattamente come mi aspettavo; l'unica domanda: cosa devo google per personalizzare il colore della "non_scroll_line"?
Andrey Lushnikov

1
Forse "capacità terminfo colore di sfondo in primo piano" (cioè leggere informazioni sul colore nella pagina di manuale terminfo). È possibile utilizzare tputper includere le sequenze di controllo appropriate nell'argomento "contenuto della riga". Con la maggior parte dei terminali, è possibile impostare la linea "ciano (6) e verde (3) su magenta (5)" con no_scroll_line top "$(tput setaf 6; tput setab 5)Node: $(tput setaf 3)foo$(tput op)" node foo.js. setafimposta il primo piano, setabimposta lo sfondo, opripristina i colori di default dei terminali. Le funzionalità del colore accettano un numero compreso tra 0 e 7, 0-15, 0 87 o 0-255, a seconda dell'emulazione del terminale.
Chris Johnsen

Ora abbiamo rilasciato pymux. Questo mostra le barre del titolo del riquadro: github.com/jonathanslenders/pymux
Jonathan Slenders

Sembra che il comportamento sia che il titolo del riquadro è impostato sul comando in esecuzione nella shell. Quindi non "si attaccherà" a meno che non stiamo eseguendo un processo di lunga durata (che sa anche come produrre la sequenza di escape per l'impostazione del titolo) all'interno.
Steven Lu

4
Si prega di dare un'occhiata alla risposta più sotto: stackoverflow.com/a/37602055/266453 tmux dalla versione 2.3 supporti titoli in confini riquadro.
Dennis G

78

Questa funzionalità è stata aggiunta a tmux in questo commit . Non è nella versione 2.2, ma sembra che lo sarà nella 2.3.

Per abilitarlo:

tmux set -g pane-border-status top

o se preferisci:

tmux set -g pane-border-status bottom

Per impostare un testo personalizzato come riga di stato del bordo del riquadro che puoi utilizzare pane-border-format, ad esempio in questo modo:

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

1
Questo mostra il numero del riquadro e un titolo predefinito. Come si cambia il pensiero?
adn

Non sono sicuro dei numeri del riquadro, ma risponde come il titolo di una finestra xterm per eseguire l'escape delle sequenze. Ad esempio, con bash, ho impostato PS1 = '[\ e] 0; \ u @ \ h: \ w \ a] $' per ottenere "user @ host: working dir /"
kevmitch

Per quanto ho capito, hai impostato quella sequenza in anticipo. Ma non esiste una scorciatoia o una combinazione di tasti che li cambi. Quindi, tmuxhai bisogno di qualche comando esterno tmuxper cambiarlo. Destra? O c'è qualche sequenza all'interno che può aggiornarlo?
adn

Sì, è sufficiente impostare la variabile nella shell in esecuzione e si aggiorna quando viene disegnato il prompt successivo. Per me sembra che tmux sia un po 'impreciso e lo aggiorni effettivamente solo quando passi a un altro pannello.
kevmitch

Puoi effettivamente usare pane-border-formatper impostare una stringa di formato personalizzata per il riquadro da visualizzare (il #{...}formato normale ). Ho modificato la tua risposta per includerla.
Dennis G

35

Dal momento tmux 2.6che puoi fare:

$ 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

Puoi vedere il titolo per riquadro in una barra di stato con:

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

Disabilita la barra di stato con:

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

Sai se c'è un modo per impedire a tmux di cambiare il titolo sotto di te? Ad esempio, se imposto il titolo di un riquadro e poi faccio qualcosa in quel riquadro, come cd $HOME, il titolo viene cambiato nel valore di $HOME. (Lo vedo su tmux 2.8.)
pdoherty926

1
@ pdoherty926 Forse hai già ricevuto la risposta, ma controlla set-window-option automatic-rename off.
noname

Ho set-option -g allow-rename offnella mia .tmux.confcartella.
Eyal Levin

1
Grazie per i suggerimenti. Ho finito per utilizzare pane-border-formate una variabile fornita dall'utente (non sono sicuro che esista un nome ufficiale per questa funzione) per controllare ciò che viene visualizzato. Ecco un esempio.
pdoherty926

14

Sto lavorando sulla barra di stato del pannello per tmux - ticket. Il mio ramo di sviluppo può essere trovato qui su github: https://github.com/jonathanslenders/tmux

In questo momento, questo già aggiunge un comando "titolo" del riquadro rinomina funzionante . Ci sono ancora alcuni bug e l'API migliorerà. L'idea è creare una barra di stato per riquadro, che può avere una certa formattazione, come la barra di stato della sessione. Come il resto di tmux, tutto dovrebbe diventare programmabile e personalizzabile. Quando sarà finito e stabile, sarà probabilmente incluso nel tmux ufficiale.


Mentre sei lì, puoi fare in modo che il titolo del riquadro diventi il ​​titolo della finestra predefinito durante un riquadro di interruzione?
djsadinoff

Questo ramo non è mai stato unito a tmux. Ma ho creato invece pymux, che ha le barre del titolo del riquadro: github.com/jonathanslenders/pymux
Jonathan Slenders

Questo comando non funziona neanche sull'ultima build (commit a24260).
adn

14

Sto usando tmux versione 2.3, penso che lo stile del bordo non sia supportato nelle versioni precedenti. Questo è ciò che ha funzionato per me:

Per ogni riquadro impostare il titolo:

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

Poi:

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

9
Almeno fino a tmux 2.6, puoi cambiare il titolo del riquadro all'interno di tmux: select-pane -T "my title"fa questo. Puoi anche impostare un'associazione di tasti quindi devi solo fornire il titolo:bind-key T command-prompt -p "New title:" 'select-pane -T "%%"'
lucasem

3
@ Lucasem forse non ho seguito questo thread, ma questa sembra la risposta.
ghiacciolo

@lucasem Non sono sicuro al 100% ma credo che il tuo metodo (che IMO è il migliore e il più semplice in questo intero thread, per le versioni recenti di tmux) funzioni solo se l' pane-border-statusopzione è impostata su qualcosa ( topo bottom).
cjauvin

11

Una gif vale più di mille parole. ( fonte )

tmux-xpanes è un divisore di terminale basato su tmux, che supporta la visualizzazione del titolo per ogni riquadro tramite l' -topzione appena aggiunta .


1
Una gif vale più di mille parole, ma se mai un link marcisce non ne vale la pena.
Finanzia la causa di Monica il

7

Sì, esiste un tale comando: tmux . Dai un nome alla tua sessione e verrà visualizzato in una barra di stato interna:

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

2
Sì, grazie per la tua risposta! Ma quindi dovrò lanciare una nuova sessione tmux in ogni riquadro solo per un titolo in fondo - un po 'eccessivo, non è vero?
Andrey Lushnikov

Non lo so. È? L'hai provato? Quanta memoria extra sta usando la sessione extra?
event_jr

sì, ho utilizzato sessioni tmux annidate fino ad oggi. Non sono sicuro del consumo di memoria e cose del genere - semplicemente non mi piace il concetto stesso perché non è puro.
Andrey Lushnikov


0

TL; DR

Aggiungi le seguenti configurazioni al tuo file di configurazione tmux (nel mio caso lo è ~/.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}"

quindi esegui:

tmux source-file ~/.tmux.con

divertirsi

Grazie a https://stackoverflow.com/a/37602055/5121972

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.