tmux prend en charge les titres par volet, mais il ne fournit pas d'emplacement par volet pour afficher ces titres.
Vous pouvez définir le titre d'un volet avec la séquence d'échappement ESC ]2;
… ESC \
(par exemple, voir la section intitulée Noms et titres dans la page de manuel tmux ). Vous pouvez le faire à partir du shell comme ceci:
printf '\033]2;%s\033\\' 'title goes here'
Le titre de chaque volet est par défaut le nom d'hôte du système. Par défaut, le titre du volet actif est affiché sur le côté droit de la ligne d'état de tmux (la valeur globale par défaut de la variable de session status-right
est "#22T" %H:%M %d-%b-%y
, qui affiche 22 caractères du titre du volet, l'heure et la date).
Ainsi, tant que vous êtes satisfait de pouvoir voir le titre du volet actif (c'est-à-dire que vous souhaitez changer de volet pour voir le titre d'un volet inactif), vous pouvez vous en tirer avec la fonctionnalité par défaut. Envoyez simplement la séquence d'échappement de réglage de titre appropriée avant de lancer la commande principale pour chaque volet.
Si vous avez absolument besoin d'une ligne dédiée pour afficher certaines informations par volet, les sessions tmux imbriquées peuvent ne pas être autant (inutiles) «exagérées» que vous ne le pensez.
Dans le cas général, pour fournir une ligne d'état inviolable sur un terminal donné, vous aurez besoin d'un (ré) émulateur de terminal complet qui se trouve entre le terminal d'origine et un nouveau terminal (un avec une ligne en moins). Une telle (ré) émulation est nécessaire pour traduire les séquences de contrôle envoyées au terminal interne et les traduire pour le terminal d'origine. Par exemple, pour maintenir une ligne d'état en bas du terminal externe, la commande
Passez à la dernière ligne.
envoyé au terminal interne doit être devenu
Passez à l'avant-dernière ligne.
une fois traduit et envoyé au terminal externe. De même, un LF envoyé au terminal interne doit devenir
Si le curseur est sur l'avant-dernière ligne, faites défiler cette ligne et toutes les lignes au-dessus d'une ligne vers le haut, pour fournir une avant-dernière ligne claire (protégeant la ligne d'état sur la dernière ligne). Sinon, envoyez un LF.
dans le terminal externe.
Des programmes comme tmux et screen ne sont que de tels réémulateurs de terminaux. Bien sûr, il existe de nombreuses autres fonctionnalités intégrées à l'émulateur de terminal, mais vous auriez besoin d'un gros morceau de code d'émulation de terminal juste pour fournir une ligne d'état fiable .
Il existe cependant une solution légère tant que
- vos programmes ( instances Node.js ) ont des interactions de terminal limitées avec les volets dans lesquels ils s'exécutent (c'est-à-dire pas de positionnement du curseur), et
- vous ne redimensionnez pas les volets pendant l'exécution de vos programmes.
Comme beaucoup d'émulateurs de terminal, tmux prend en charge une commande de contrôle de terminal «définir la région de défilement» dans ses volets. Vous pouvez utiliser cette commande pour limiter la zone de défilement aux N-1 lignes supérieures (ou inférieures) du terminal et écrire une sorte de texte d'identification d'instance dans la ligne sans défilement.
Les restrictions (pas de commandes de déplacement du curseur autorisées, pas de redimensionnement) sont requises car le programme qui génère la sortie (par exemple une instance Node.js ) n'a aucune idée que le défilement a été limité à une région particulière. Si le programme de génération de sortie déplaçait le curseur en dehors de la région de défilement, alors la sortie pourrait devenir brouillée. De même, l'émulateur de terminal réinitialise probablement automatiquement la région de défilement lorsque le terminal est redimensionné (ainsi la «ligne sans défilement» finira probablement par défiler).
J'ai écrit un script qui utilise tput
pour générer les séquences de contrôle appropriées, écrire dans la ligne sans défilement et exécuter un programme après avoir déplacé le curseur dans la région de défilement:
#!/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"
Vous pouvez l'utiliser comme ceci:
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'
Le script doit également fonctionner en dehors de tmux tant que le terminal prend en charge et publie ses capacités csr
et cup
terminfo.