Fenstertitel in Tmux

88

Auf meinem lokalen Computer werden 3 node.js-Instanzen gleichzeitig ausgeführt. Jedes hat einen eigenen Bereich in einem tmux-Fenster namens "Server". Das Problem ist, dass es nicht so einfach ist herauszufinden, welcher Knoten in welchem ​​Bereich ausgeführt wird, da die Protokolle ähnlich sind.

Was ich brauche, ist ein Titel für jedes Fenster. Wie ich erfahren habe, hat tmux selbst nicht die Funktion: Es hat nur Titel für Fenster und nicht für Fenster. Das Starten einer separaten tmux-Sitzung in jedem Bereich für jede node.js-Instanz sieht aus wie ein Overkill.

Gibt es also ein kleines Programm, das einen Befehl startet und dessen Ausgabe mit einer bestimmten Statusleiste umschließt?

Danke im Voraus

Andrey Lushnikov
quelle
1
tmux ab Version 2.3 unterstützt Fenstertitel
Dennis G

Antworten:

80

tmux unterstützt Titel pro Bereich, bietet jedoch keinen Speicherort pro Bereich für die Anzeige dieser Titel.

Sie können den Titel eines Fensters mit der Escape-Sequenz ESC ]2;… ESC festlegen\ (siehe z. B. den Abschnitt Namen und Titel in der tmux- Manpage). Sie können dies von der Shell aus wie folgt tun:

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

Der Titel jedes Fensters ist standardmäßig der Hostname des Systems. Standardmäßig wird der Titel des aktiven Fensters auf der rechten Seite der tmux- Statuszeile angezeigt (der globale Standardwert der Sitzungsvariablen status-rightlautet "#22T" %H:%M %d-%b-%y22 Zeichen des Titels des Fensters , der Uhrzeit und des Datums).

Solange Sie damit zufrieden sind, den Titel des aktiven Fensters sehen zu können (dh bereit zu sein, die Fenster zu wechseln, um den Titel eines inaktiven Fensters anzuzeigen), können Sie mit der Standardfunktionalität auskommen. Senden Sie einfach die entsprechende Escape-Sequenz für die Titeleinstellung, bevor Sie den Hauptbefehl für jedes Fenster starten.


Wenn Sie unbedingt eine Standleitung benötigen, um Informationen pro Bereich anzuzeigen, sind verschachtelte tmux- Sitzungen möglicherweise nicht so viel (unnötiger) „Overkill“, wie Sie vielleicht zuerst denken.

Im allgemeinen Fall benötigen Sie einen vollständigen Terminal- (Re-) Emulator, der sich zwischen dem ursprünglichen Terminal und einem neuen Terminal befindet (eines mit einer Zeile weniger), um eine unverletzte Statuszeile auf einem bestimmten Terminal bereitzustellen. Eine solche (Re-) Emulation ist erforderlich, um an das innere Terminal gesendete Steuersequenzen zu übersetzen und für das ursprüngliche Terminal zu übersetzen. Um beispielsweise eine Statuszeile am unteren Rand des äußeren Terminals beizubehalten, geben Sie den Befehl ein

Gehen Sie zur letzten Zeile.

an das innere Terminal gesendet werden muss

Gehen Sie zur vorletzten Zeile.

wenn für übersetzt und an das äußere Terminal gesendet. Ebenso muss ein an das innere Terminal gesendeter LF werden

Befindet sich der Cursor in der vorletzten Zeile, scrollen Sie diese Zeile und alle darüber liegenden Zeilen um eine Zeile nach oben, um eine klare vorletzte Zeile zu erhalten (Schutz der Statuszeile in der letzten Zeile). Andernfalls senden Sie einen LF.

im äußeren Terminal.

Programme wie tmux und screen sind solche Terminal- Reemulatoren . Sicher, es gibt viele andere Funktionen, die um den Terminalemulator gewickelt sind, aber Sie würden einen großen Teil des Terminalemulationscodes benötigen, um eine zuverlässige Statuszeile bereitzustellen .


Es gibt jedoch eine leichte Lösung, solange

  1. Ihre Programme ( Node.js- Instanzen) haben begrenzte Terminalinteraktionen mit den Fenstern, in denen sie ausgeführt werden (dh keine Cursorpositionierung)
  2. Sie ändern die Größe der Fenster nicht, während Ihre Programme ausgeführt werden.

Wie viele Terminalemulatoren unterstützt tmux in seinen Fenstern einen Terminalsteuerungsbefehl zum Festlegen des Bildlaufbereichs. Mit diesem Befehl können Sie den Bildlaufbereich auf die oberen (oder unteren) N-1-Zeilen des Terminals beschränken und eine Art instanzidentifizierenden Text in die nicht scrollende Zeile schreiben.

Die Einschränkungen (keine Cursorbewegungsbefehle zulässig, keine Größenänderung) sind erforderlich, da das Programm, das die Ausgabe generiert (z. B. eine Node.js- Instanz), keine Ahnung hat, dass das Scrollen auf einen bestimmten Bereich beschränkt ist. Wenn das Ausgabeerzeugungsprogramm den Cursor außerhalb des Bildlaufbereichs bewegt, kann die Ausgabe verstümmelt werden. Ebenso setzt der Terminalemulator den Bildlaufbereich wahrscheinlich automatisch zurück, wenn die Größe des Terminals geändert wird (sodass die „nicht scrollende Zeile“ wahrscheinlich weggescrollt wird).

Ich habe ein Skript geschrieben, mit tputdem die entsprechenden Steuersequenzen generiert, in die nicht scrollende Zeile geschrieben und ein Programm ausgeführt werden, nachdem der Cursor in den Bildlaufbereich bewegt wurde:

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

Sie könnten es so verwenden:

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'

Das Skript sollte auch außerhalb von tmux funktionieren , solange das Terminal seine csrund cupterminfo-Funktionen unterstützt und veröffentlicht .

Chris Johnsen
quelle
Ihr Skript funktioniert genau so, wie ich es erwartet habe. die einzige frage: was soll ich googeln um die farbe der "non_scroll_line" anzupassen?
Andrey Lushnikov
1
Möglicherweise "Terminfo-Fähigkeit Vordergrund Hintergrundfarbe" (dh lesen Sie über Farbe in Terminfo Manpage). Sie können verwenden tput, um die entsprechenden Steuersequenzen in das Argument "Zeileninhalt" aufzunehmen. Bei den meisten Terminals können Sie die Linie mit „Cyan (6) und Grün (3) auf Magenta (5)“ mit festlegen no_scroll_line top "$(tput setaf 6; tput setab 5)Node: $(tput setaf 3)foo$(tput op)" node foo.js. setafsetzt den Vordergrund, setabsetzt den Hintergrund,op setzt die Standardfarben der Terminals zurück. Die Farbfunktionen können je nach Terminalemulation zwischen 0 und 7, zwischen 0 und 15, zwischen 0 und 87 und zwischen 0 und 255 liegen.
Chris Johnsen
Wir haben jetzt Pymux veröffentlicht. Daraufhin werden Titelleisten des Fensters angezeigt: github.com/jonathanslenders/pymux
Titelleisten des Fensters an
Es scheint, dass das Verhalten darin besteht, dass der Fenstertitel auf den Befehl gesetzt wird, der in der Shell ausgeführt wird. Es bleibt also nicht "hängen", es sei denn, wir führen einen langlebigen Prozess aus (der auch weiß, wie die Escape-Sequenz für die Titeleinstellung ausgegeben wird).
Steven Lu
4
Bitte werfen Sie einen Blick auf die Antwort weiter unten: stackoverflow.com/a/37602055/266453 tmux ab Version 2.3 unterstützt Titel in Fensterrahmen.
Dennis G
78

Diese Funktionalität wurde tmux in diesem Commit hinzugefügt . Es ist nicht in Version 2.2, aber es sieht so aus, als ob es in 2.3 sein wird.

So aktivieren Sie es:

tmux set -g pane-border-status top

oder wenn Sie es vorziehen:

tmux set -g pane-border-status bottom

Um einen benutzerdefinierten Text als Statusleiste für den Fensterrand festzulegen, können Sie Folgendes verwenden: pane-border-formatz.

tmux set -g pane-border-format "#{pane_index} #{pane_current_command}"
kevmitch
quelle
1
Hier werden die Nummer des Fensters und ein Standardtitel angezeigt. Wie änderst du es gedacht?
20.
Ich bin mir bei den Fensternummern nicht sicher, aber es reagiert wie ein xterm-Fenstertitel, um Sequenzen zu entkommen. Zum Beispiel habe ich mit bash PS1 = '[\ e] 0; \ u @ \ h: \ w \ a] $' gesetzt, um "user @ host: working dir /"
kevmitch
Soweit ich weiß, haben Sie diese Reihenfolge vorab festgelegt. Es gibt jedoch keine Tastenkombination oder Tastenkombination, die sie ändert. Also, tmuxSie müssen einige Befehle außerhalb , tmuxes zu ändern. Richtig? Oder gibt es eine Sequenz, die es aktualisieren kann?
und
Ja, Sie haben die Variable einfach in der laufenden Shell festgelegt und sie wird aktualisiert, wenn die nächste Eingabeaufforderung gezeichnet wird. Für mich scheint tmux ein wenig skizzenhaft zu sein und aktualisiert es nur, wenn Sie zu einem anderen Bereich wechseln.
Kevmitch
Sie können tatsächlich pane-border-formateine benutzerdefinierte Formatzeichenfolge festlegen, die im Bereich angezeigt werden soll (das übliche #{...}Format). Ich habe Ihre Antwort so bearbeitet, dass sie dies enthält.
Dennis G
31

Da können tmux 2.6Sie tun:

$ 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

Sie können den Titel pro Bereich in einer Statusleiste anzeigen mit:

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

Deaktivieren Sie die Statusleiste mit:

$ tmux set pane-border-status off       # For current window
$ tmux set -g pane-border-status off    # For all windows
Eyal Levin
quelle
Wissen Sie, ob es eine Möglichkeit gibt, zu verhindern, dass tmux den Titel unter Ihnen ändert? Wenn ich beispielsweise den Titel eines Fensters festlege und dann etwas in diesem Bereich mache, wie z. B. cd $HOME, wird der Titel in den Wert von geändert $HOME. (Ich sehe dies auf tmux 2.8.)
pdoherty926
1
@ pdoherty926 Vielleicht hast du schon die Antwort bekommen, aber check out set-window-option automatic-rename off.
noname
Ich habe set-option -g allow-rename offin meiner .tmux.confAkte.
Eyal Levin
1
Danke für die Vorschläge. Ich habe pane-border-formateine vom Benutzer bereitgestellte Variable verwendet (ich bin mir nicht sicher, ob es einen offiziellen Namen für diese Funktion gibt), um zu steuern, was angezeigt wird. Hier ist ein Beispiel.
pdoherty926
14

Ich arbeite an der Statusleiste des Fensters für tmux - ticket. Mein Entwicklungszweig finden Sie hier auf github: https://github.com/jonathanslenders/tmux

Im Moment wird bereits ein funktionierender Befehl zum Umbenennen des "Titels" hinzugefügt. Es gibt immer noch einige Fehler, und die API wird verbessert. Die Idee ist, eine Statusleiste pro Bereich zu erstellen, die eine gewisse Formatierung haben kann, wie z. B. die Sitzungsstatusleiste. Wie der Rest von tmux sollte alles skriptfähig und anpassbar werden. Wenn es fertig und stabil ist, wird es wahrscheinlich im offiziellen tmux enthalten sein.

Jonathan Slenders
quelle
Können Sie es so gestalten, dass der Fenstertitel während eines Unterbrechungsfensters zum Standardfenstertitel wird?
Djsadinoff
Dieser Zweig wurde nie in tmux zusammengeführt. Aber ich habe stattdessen Pymux erstellt, das Titelleisten im Bereich hat: github.com/jonathanslenders/pymux
Jonathan Slenders
Dieser Befehl funktioniert auch beim letzten Build nicht (Commit a24260).
20.
14

Ich verwende tmux Version 2.3. Ich denke, der Rahmenstil wird in früheren Versionen nicht unterstützt. Das hat bei mir funktioniert:

Legen Sie für jeden Bereich den Titel fest:

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

Dann:

tmux set -g pane-border-format "#{pane_index} #T"
OriG
quelle
9
Mindestens so aktuell wie tmux 2.6 können Sie den Fenstertitel in tmux ändern: select-pane -T "my title"tut dies. Sie können sogar eine Schlüsselbindung einrichten, sodass Sie nur den Titel bind-key T command-prompt -p "New title:" 'select-pane -T "%%"'
angeben
3
@ Lucasem Vielleicht bin ich diesem Thread nicht gefolgt, aber das scheint die Antwort zu sein.
Eiszapfen
@lucasem Ich bin nicht 100% sicher, aber ich glaube, dass Ihre Methode (welche IMO die beste und einfachste in diesem gesamten Thread ist, für neuere Versionen von tmux) nur funktioniert, wenn die pane-border-statusOption auf etwas ( topoder bottom) gesetzt ist.
Cjauvin
11

Ein GIF sagt mehr als tausend Worte. ( Quelle )

tmux-xpanes ist ein tmux-basierter Terminalteiler, der die Anzeige von Titeln für jeden Bereich über die neu hinzugefügte -tOption unterstützt.

navigaid
quelle
1
Ein GIF sagt mehr als tausend Worte, aber wenn es jemals verrottet, ist es nichts wert.
Fund Monica Klage
7

Ja, es gibt einen solchen Befehl : tmux. Geben Sie Ihrer Sitzung einen Namen und dieser wird in einer inneren Statusleiste angezeigt:

TMUX=0 tmux new-session -s my-new-session
event_jr
quelle
2
Ja, danke für deine Antwort! Aber daher muss ich in jedem Bereich eine neue tmux-Sitzung starten, nur für einen Titel im unteren Bereich - eine Art Overkill, nicht wahr?
Andrey Lushnikov
Ich weiß es nicht. Ist es? Hast du es versucht? Wie viel zusätzlichen Speicher verwendet die zusätzliche Sitzung?
event_jr
Ja, ich habe bis heute verschachtelte tmux-Sitzungen verwendet. Ich bin mir nicht sicher über den Speicherverbrauch und solche Dinge - ich mag das Konzept selbst einfach nicht, weil es nicht rein ist.
Andrey Lushnikov
0

TL; DR

Hängen Sie die folgenden Konfigurationen an Ihre tmux-Konfigurationsdatei an (in meinem Fall ~/.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}"

dann renne:

tmux source-file ~/.tmux.con

geniesse es

Vielen Dank an https://stackoverflow.com/a/37602055/5121972

sstruct
quelle