blog · git · desktop · images · contact


„xiate is a terminal emulator“

2015-10-04

Terminals sind ein Dauerthema. Muss man mal drüber reden.

Ablösung für XTerm gesucht

Kürzlich habe ich über UW ttyp0 geschrieben, einen „monospaced bitmap font“ mit ziemlich guter Unicode-Abdeckung. Das ist seitdem auch mein primär genutzter Font in Terminals geworden.

Seit vielen Jahren benutze ich XTerm als Terminal-Emulator. Was man bei XTerm wissen muss, ist, dass man genau einen Font auswählen kann und den benutzt er dann. Klingt komisch, ist aber so. Das ist nicht bei allen Terminals so: Bei manch anderen kann man mehrere Fonts mit Prioritäten angeben. Wenn das Terminal dann ein Zeichen anzeigen soll, das es im ersten Font nicht gibt, dann sucht es dieses Zeichen im zweiten Font, dann möglicherweise im dritten Font und so weiter. Dieser Mechanismus wird „Font-Fallback“ oder „Fallback Fonts“ genannt.

Wie schon erwähnt, beherrscht XTerm das nicht. Das hat dann zur Folge, dass der benutzte Font von außergewöhnlich guter Qualität sein muss. Aufrechte, kursive, fette Varianten muss es geben und das dann auch noch in verschiedenen Größen. Da ich nun gerne Bitmap-Fonts benutze, muss jedes Zeichen de facto manuell gestaltet werden. In der Summe ist das eine enorme Arbeit. Uwe Waldmann hat sich diese Arbeit bei UW ttyp0 mit hervorragendem Ergebnis gemacht. Unicode umfasst aber so viele Zeichen, dass es unmöglich ist, die alle in einem Font unterzubringen. Trotz ttyp0s guter Qualität kam es also wieder vor, dass mir Zeichen fehlten.

Das ganze Dilemma entsteht, wie gesagt, nur durch das Fehlen von Font-Fallback in XTerm. Obwohl ich mit XTerm all die Zeit über sehr zufrieden war, war das etwas, das mir keine Ruhe ließ.

Welche Terminals gibt es denn sonst noch?

Allen voran st. Das wurde von Leuten aus der suckless-Community geschrieben, weshalb man da eine hohe Codequalität erwarten kann. Ich finde, st sollte man als erstes ausprobieren, wenn man sich nach einem neuen Terminal umschaut. Mittlerweile lässt st auch keine wichtigen Features mehr vermissen. Ich würde es auch verwenden, aber es gibt da ein kleines Problemchen.

st braucht einen eigenen Eintrag in der terminfo-Datenbank. So gut wie alle Anwendungen benutzen diese Datenbank, um herauszufinden, was das Terminal kann und welche Escape-Sequenzen dazu notwendig sind. Doof nur, dass immer die lokale Datenbank auf dem jeweiligen System benutzt wird. Verbinde ich mich also per SSH auf einen anderen Rechner, dann fehlt dort unter Umständen der Eintrag für st. Nicht einmal „less“ möchte dann mehr funktionieren.

Ich habe es nun leider mit mehreren hundert Nodes zu tun, von denen manche auch noch sehr alt sind. Das ist dann sehr umständlich bis unmöglich, überall dort den Eintrag für st zu hinterlegen. Folge: Alles kaputt. Ich könnte jetzt natürlich so tun, als wäre mein st ein XTerm, das fühlt sich aber nicht nach einer sauberen Lösung an und zwischen den beiden ist auch keine Kompatibilität garantiert.

(Ich finde es auch nicht toll, dass st selbst keinen Scrollback-Buffer hat. Man muss etwas wie tmux oder dvtm benutzen. Meh.)

Trotzdem finde ich, dass st ein tolles Projekt ist. Die Jungs haben den Anspruch, Sachen richtig zu machen und nicht so, dass es halt einfach irgendwie funktioniert. Der Code soll sauber bleiben. Projekte dieser Art sind enorm wichtig. Daher: Ausprobierbefehl für st! :-)

Okay, was gibt es denn sonst noch?

rxvt und seine Varianten. Naja, hier gibt es dasselbe Problem wie bei st mit dem terminfo-Eintrag. Außerdem ist Font-Fallback hier nicht besonders gut. Das ist zwar auch in st etwas hakelig, aber bei st könnte ich aufgrund der Codequalität von st aktiv daran arbeiten, die Situation zu verbessern. rxvt ist riesig und da will man seine Finger nicht reinstecken. Und wieso gibt es im AUR ein Paket namens „rxvt-unicode-patched“? Sind da Patches für den sauberen Betrieb notwendig? Achja, und für Unicode muss man rxvt-unicode benutzen, was wiederum schonmal ein Fork von rxvt ist, heißt also, rxvt wurde nicht gezielt mit Unicode-Kompatibilität im Hinterkopf geschrieben. Ich sehe auch nicht ein, wieso ein Terminal Perl-Extensions unterstützen können muss.

Schlussendlich gibt es dann VTE. Das ist eine Bibliothek aus dem GNOME-Umfeld. Sie wird vom GNOME-Terminal selbst benutzt und auch von einigen anderen Programmen. Erwähnenswert sind hier sakura, LilyTerm und ROXTerm. Bei allen steht irgendwie „lightweight“ dran und in gewisser Weise sind sie das auch. Ist auch nur logisch, denn all die harte Arbeit wird von VTE erledigt.

Von denen hat mir aber keines wirklich zugesagt. Alle haben deutlich mehr Features, als ich benötige. Ich brauche keine Tabs oder Menüs oder Runtime-Konfiguration. Ich brauche einfach nur ein Terminal.

VTE selbst sah aber interessant aus. Font-Fallback funktioniert hier prächtig. Ich schätze, das liegt an der Nähe zum GNOME-Projekt, denn die Jungs achten sehr darauf, dass ihre Sachen auch in anderen Ländern sinnvoll funktionieren. Auch schön ist, dass VTE sich von Haus aus als XTerm ausgibt, weshalb das SSH-Problem hier nicht existiert – jedes UNIX-System kennt XTerm.

xiate betritt die Bühne

Weil ich so viele Dinge selbst mache, werde ich immer wieder gefragt, was das denn soll. Dadurch spüre ich mittlerweile schon selbst einen Rechtfertigungsdruck – ungerechtfertigterweise, aber so ist das halt. Naja, schauen wir uns das mal an: Ich benutze eine stark veränderte Version von dwm. Ich habe lariza gebaut. Mit der Zeit habe ich „aus Versehen“ viele Tools neugeschrieben. Ich schreibe einfach gerne meinen eigenen Code, denn dabei lernt man etwas. Man versteht die meisten Sachen nicht wirklich, solange man sie nicht selbst gemacht hat. Natürlich ist es einfacher, fertige Lösungen zu verwenden. Ich will das aber selbst machen. Das ist mein Hobby. Und selbst dann, wenn man eine fertige Bibliothek wie VTE benutzt, lernt man noch etwas dazu. Bei allem, was ich hier tue, geht’s ums Lernen.

Nachdem ich dann kurz das VTE-Manual überflogen hatte, war ich auch recht zuversichtlich, dass daraus etwas werden kann. Ich schrieb also mein eigenes VTE-Frontend.

xiate ist das Ergebnis. Es ist ein „eher einfaches“ Terminal. Du kriegst nämlich nur ein Terminal-Fenster und fertig. Es gibt keine Tabs, keine Menüs, keinen Schnickschnack. Als Zielgruppe hat xiate daher die typischen „Power-User“, die mit Tiling-Window-Manager unterwegs sind.

Zwar habe ich xiate minimalistisch gehalten, das Programm kann aber trotzdem nicht als „suckless“ durchgehen. Wieso? Weil VTE benötigt wird. VTE wiederum benötigt GTK+ 3 und GTK+ 3 zieht einen ganzen Haufen Abhängigkeiten und enorme Mengen an Code nach sich. Das ist dieselbe Situation wie bei lariza und auch bei surf: Der Code des „Frontends“ ist zwar völlig in Ordnung, aber die Bibliothek hinten dran ist gigantisch.

Trotzdem ist xiate im Vergleich mit den meisten anderen Terminals ein Fliegengewicht und schön „hackable“.

Zum Client-Server-Modell

VTE hat ein ganz großes Problem: Die Initialisierungsphase ist sehr teuer. Das ist eine logische Schlussfolgerung aus den fetten Bibliotheken, die hinten dranhängen: GTK, GLib, Gdk, Pango, was auch immer. Das hat auch nichts mit xiate zu tun, sondern ist bei allen VTE-Terminals so. Langsame Start-Zeiten sind aber ein „no go“ für „Power-User“. Klar, wenn man ein durchschnittlicher GNOME-User ist, dann fällt das nicht weiter ins Gewicht, weil man ohnehin erst einmal zur Maus greifen, das Icon klicken und dann mit der Hand wieder zurück zur Tastatur muss. Das ist dann schon okay, wenn das einen Moment dauert. Ich will aber nur auf „Super + Enter“ drücken und dann hat das Terminal da zu sein. Zack. Das darf nicht länger als ein paar Millisekunden dauern.

Was macht denn da?

Ich habe mich letztendlich dazu entschieden, die Idee eines Client-Server-Modells von rxvt zu übernehmen. Man startet also „xiate“ in seiner „~/.xinitrc“ (oder wo auch immer) und sagt diesem Prozess dann später, dass es Fenster öffnen soll. Dafür stellt er ein UNIX-Socket bereit. Der Client, „xiatec“, ist dann einfach nur noch ein Shell-Skript um socat herum, welches auf dieses Socket schreibt. Das Öffnen des aller ersten Fensters dauert nach wie vor einen Moment, aber alle folgenden Fenster sind dann umgehend da.

Dieses Modell ist durchaus problematisch. Am offensichtlichsten ist, dass alle Terminal-Fenster verschwinden, falls mal der Daemon abstürzen sollte. Ich kann noch nicht abschätzen, wie häufig das so passiert, weil ich VTE noch nicht lange genug benutze. Ich bin mir aber leider ziemlich sicher, dass auch VTE früher oder später mal abstürzen wird (so wie die meiste Software). Muss man sehen.

Außerdem: „xiatec“ schreibt nur auf das Socket und beendet sich dann sofort wieder. Soetwas geht also nicht:

#!/bin/bash

# ... mache irgendwas ...

xiatec -e vim $somefile

# ... mache hier weiter, sobald das Fenster geschlossen ist ...

Ich glaube aber, dass das okay ist. Warum sollte auch „xiatec“ blockieren müssen, bis das Fenster geschlossen ist? Nur, weil andere Terminals das so machen? Ich sehe da noch keinen Grund, bin aber offen für Input.

So oder so, das Client-Server-Modell würde ich schon gerne abschaffen.

Abschluss

Ich benutze erst einmal weiterhin UW ttyp0. In den wenigen Wochen habe ich mich einfach völlig daran gewöhnt und jetzt wirkt Terminus ein bisschen seltsam auf mich. ;-)

Screenshot.

xiate benutze ich jetzt seit ungefähr zwei Wochen, sowohl auf der Arbeit als auch zu Hause, jeweils viele Stunden am Tag. Bin eigentlich sehr zufrieden damit.

Comments?