Xterm.js: Terminal gibt keine Echtfarben wieder

Erstellt am 16. Jan. 2017  ·  20Kommentare  ·  Quelle: xtermjs/xterm.js

Hilfreichster Kommentar

Hallo. Irgendwelche Updates dazu? Ich kann es kaum erwarten, dass es funktioniert 😃

Alle 20 Kommentare

Kann es kaum erwarten. Ich habe bei hterm versucht, Truecolor-Unterstützung zu erhalten, aber ich denke, dies ist eine viel bessere Option.

Die Implementierung muss hier erfolgen https://github.com/sourcelair/xterm.js/blob/365a9f949cc1acfb6c4649ee1d85da3bbc60f928/src/InputHandler.ts#L1276

Der schwierige Teil besteht darin, zu bestimmen, wie wir die Farben für die Zeichen speichern und dann rendern (wahrscheinlich Inline- style Attribute). Etwas wie https://github.com/sourcelair/xterm.js/pull/450 würde wahrscheinlich das Hinzufügen der Attribute vereinfachen.

Vielleicht schaue ich mir das mal an, wenn ich Zeit habe, aber ich kann nicht sagen, dass ich mich mit Steuersequenzen so gut auskenne.

Ich habe einen Blick auf http://invisible-island.net/xterm/ctlseqs/ctlseqs.html geworfen , konnte aber nichts über True Color oder 24-Bit-Farbe finden. Übersehe ich etwas oder gibt es eine andere Ressource, die dies behandelt?

@cnsumner xterm kann derzeit keine True Color anzeigen, unterstützt jedoch eine der vorgeschlagenen Escape-Sequenzen. Mehr dazu können Sie hier lesen: https://gist.github.com/XVilka/8346728
Übrigens ist dies teilweise im ECMA-48-Standard spezifiziert.

Stellen Sie einen chaotischen Proof of Concept zusammen, um eine bessere Vorstellung davon zu bekommen, was wir hier tun müssen https://github.com/Tyriar/xterm.js/tree/484_truecolor

image

Dinge, die getan werden müssen:

  • Der Zweig fügt derzeit jedem Zeichen, das seine 'Truecolor' darstellt, eine weitere Zahl im Format 0x1RRGGBB (fg) oder 0x0RRGGBB (bg) hinzu, was in eine 32-Bit-Ganzzahl passt
  • Es muss sowohl fg- als auch bg-Farben unterstützen und in der Lage sein, echte und normale Farben zu mischen
  • curTrueColor ist super hässlich
  • Unterstützung invers
  • Farbmarkierungen müssen gelöscht werden, wenn Zellen wiederverwendet werden
  • Es könnte an der Zeit sein, die Codierung von Zeichen zu überdenken. Das aktuelle Format ist:

    [attribute, character, width]
    
    • attribute : Eine 32-Bit-Ganzzahl, die ascii fg, ascii bg und Flags (fett, unterstrichen, blinken, invers, unsichtbar) enthält, nicht alle Bits werden verwendet
    • char : Entweder die leere Zeichenfolge (für Zeichen mit der Breite 0, die breite Zeichen auffüllen) oder eine einstellige Unicode-Zeichenfolge
    • width : Die Breite des Zeichens kann derzeit 0, 1 oder 2 sein, aber dies könnte mehr beinhalten, um Tabs richtig zu unterstützen https://github.com/sourcelair/xterm.js/issues/734
  • Die letztendliche Lösung sollte kompakt für den Speicher und auch schnell zugänglich sein, wobei es wahrscheinlich die beste Idee ist, bei einem Array, binären Flags und Bitverschiebung für Daten zu bleiben.

@Tyriar
Ja, der Speicherverbrauch wird explodieren, wenn er nicht für geringen Verbrauch optimiert ist. Vielleicht kann es zusammen mit width gepackt werden, dieses Feld wird wahrscheinlich nicht größer als 16 und verbraucht nur 4 Byte (normalerweise ist der Tab auf 4 oder 8 eingestellt). Dies lässt Platz für eine RGB-Definition* (vorausgesetzt, width ist eine 32-Bit-Ganzzahl). Ich bin mir nicht sicher, wie viele Bits in attribute , vielleicht kann die zweite RGB-Definition gehen .

Es sieht so aus, als ob Attribute derzeit 9 Byte für bg, 9 Byte für bg und 5 Byte für Flags verbrauchen, so dass am Ende viel Platz bleibt, um die Breite einzudrücken. Die RGB-Definitionen benötigen jeweils 24 Byte (8*3).

Hier ist der (etwas komplizierte) platzsparende Ansatz, den Sie meiner Meinung nach vorschlagen:

[char, attr1, attr2]

Wobei attr1 ist (29 Bit):

  • Breite: 4 Bit
  • ist 256 Farben- oder Truecolor-Flag: 1 Bit
  • bg-Farbe: 24 Bit

Und attr2 ist (30 Bit):

  • Flags: 5 Bit
  • ist 256 Farbe oder Truecolor-Flag: 1 Bit
  • fg-Farbe: 24 Bit

Ein einfacherer Ansatz würde eine Zahl speziell für Attribute verwenden:

[char, attr, truecolorBg, truecolorFg]

Wo ist attr:

  • Breite: 4 Byte
  • Flags: 5 Byte
  • 256 bg Farbe: 9 Byte
  • 256 fg Farbe: 9 Byte

Ich möchte diese Details so gerne kapseln, da sie die Dinge wirklich komplizieren, ich frage mich, ob wir mit Typoskript Getter irgendwie auf ein Array setzen können. Die Verwendung eines Objekts war 20x langsamer als ein Array, das auf einem Mikro-Benchmark basiert, den ich mit jsperf durchgeführt habe.

Was auch immer wir tun, das Format muss sehr gut dokumentiert werden. Im Moment müssen Sie es selbst herausfinden, indem Sie sich InputHandler.charAttributes .

Noch ein paar Gedanken zum Speicher sparen:

  • Wenn ein Zeichen eine Breite > 1 hat, müssen wir für die folgenden Zeichen eigentlich gar keine Daten speichern. Die "leeren Zeichen" sind als Workaround da und würden wahrscheinlich gut funktionieren, wenn sie null .
  • Normalerweise wird ein Satz von Zeichen gestylt, was bedeutet, dass Attribute von einer Zeichenfolge gemeinsam genutzt werden können.
  • Attribute können zwischengespeichert werden und jedes Zeichen verwendet einen Zeiger auf einen der zwischengespeicherten Werte.

Ja, ich denke, auf den meisten JS-Engines sind Arrays mit Indexzugriff immer noch schneller als Objekte und ihre Eigenschaftsauflösung. V8 hat jedoch einige zusätzliche Optimierungen für Objekte erhalten. Aufbau und GC-technisch ist ein Array aufgrund des viel einfacheren Speicherlayouts schneller (dieser Nachteil kann durch die Wiederverwendung vorhandener Objekte vermieden werden).

Ich habe hier keine Ahnung vom richtigen Layout, das Problem ist, dass jedes stark gepackte Zeug aufgrund der erforderlichen Transformationen Laufzeiteinbußen verursacht. (Dies ist ein Grund, Bitfelder in C nicht zu verwenden, wenn Speicher keine Rolle spielt - die erforderlichen Schiebeoperationen verschmutzen den Befehlscache, was zu Cache-Fehltreffern führt - der Code läuft viel langsamer).
Imho werden nur Tests zeigen, was hier am besten funktioniert.

@jerch interessant, ich habe zur Vereinfachung gerade eine 4-Nummern-Version in https://github.com/sourcelair/xterm.js/pull/756.

Es wird also erwartet, dass der Speicher hier ungefähr beträgt: 5 * (1000 Scrollback) * (8 Byte auf einem 64-Bit-Rechner) * 80 = 3,2 MB (vor dem Overhead des js-Arrays). Die tatsächliche Breite eines typischen VS Code-Terminals würde sich verdoppeln, wenn wir das aktuelle Format beibehalten. Scheint jetzt ziemlich steil zu sein, wenn ich es mir ansehe, zumal Benutzer oft mehr als 1000 Scrollbacks und mehrere aktive Terminals haben. Der nachfolgende Leerraum, der wirklich nicht viel hinzufügt und genauso gut null sein könnte, wäre wahrscheinlich ein ziemlich großer Gewinn.

Die Idee des Attribut-/Farbset-Cache scheint ebenfalls vielversprechend zu sein, solange es eine gute Möglichkeit für den schnellen Zugriff gibt. Eine leichte, baumähnliche Struktur wäre ideal (schneller Zugriff für die am häufigsten verwendeten Attribute).

Es könnte sich auch lohnen, Zeilendaten-Arrays wiederzuverwenden, wenn sie getrimmt werden, anstatt sie einfach zu verwerfen ( z. B. hier ).

Ja, und mit dem Engine-Overhead im Hinterkopf wird es noch größer - alles in einem Array oder Objekt wird als Referenz gespeichert, im Grunde ein Zeiger auf den Inhalt. Dichte js-Arrays haben hier einen kleinen Vorteil, sie werden als C-ähnliches Array irgendwo weiter unten gebildet (also eigentlich ArrayLists). Sparse Arrays und andere Objekte werden mit etwas Baummagie erstellt, um die Eigenschaftsauflösung zu lösen.
Für 64bit fügt das Referenzding also 5 * 8 weitere Bytes pro Zelle hinzu (es verdoppelt im Grunde Ihre obige Berechnung - 6,4 MB). Der Inhalt kann neben dem "echten Inhalt" noch mehr Bytes hinzufügen, dies hängt jedoch von der tatsächlichen Implementierung des Typs Integer und String ab.

Vielleicht kann ein TypedArray das lösen. Dort kann sich das ganzzahlige Zeug direkt an der Indexposition im Speicher befinden, ohne dass eine zusätzliche Umleitung erforderlich ist. asm.js arbeitet grundsätzlich nur auf diesen.

Hier ist ein kurzer Micro-Benchmark zum Vergleich von TypedArray und js-Array für die Erstellung und Dateneinfügung: http://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d

Das TypedArray läuft mit FF und Chrome auf meinem Rechner 10-mal schneller. Dies könnte an der Vorbelegung liegen, habe dies nicht mit js-Array getestet, da davon abgeraten wird. Ich bin mir nicht sicher, ob die JITs die Tatsache erkennen, dass der Wert nur alle 8 Byte um 1 erhöht wird, und dies sogar optimieren. Dann ist der Benchmark nutzlos.

Der Zugriff ist bei einem TypedArray etwas schlechter (vielleicht aufgrund der Number Konvertierung), der Speicherverbrauch ist bei einem TypedArray viel besser.

Der Nachteil eines TypedArrays ist der statische Speicherblock, wenn es um Ersatzdaten (Tricks, um Daten zu vermeiden, funktioniert hier überhaupt nicht, der Speicher ist sowieso "verloren") oder die Größenänderung mit Content Wrapping. Es ist schwer, es richtig zu machen, und wahrscheinlich müssen große Datenmengen immer wieder kopiert werden.

Hallo. Irgendwelche Updates dazu? Ich kann es kaum erwarten, dass es funktioniert 😃

Arbeitet jemand aktiv an diesem Problem? Wird es woanders diskutiert? @chabou @Tyriar? Hilft Microsoft angesichts der Verwendung in VS Code?

Dies ist das letzte verzögerte Problem bei der Verwendung von Hyper in WSL unter Windows 10, um einen anständigen Dev-CLI-Workflow bereitzustellen, der tmux und vim/neovim unterstützt. Andere Terminal-Emulatoren, die mit WSL verwendet werden können, sind einfach nicht schön anzusehen, wsltty ist in der Nähe, aber Tab- und Plugin-Unterstützung fehlt ...

@vastbinderj Warum bietet Ihnen die fehlende True-Color-Unterstützung keinen anständigen Dev-CLI-Workflow? Ehrliche Frage.

@szmarczak und @vastbinderj
Dieses Problem steht immer noch auf der Tagesordnung, wird aber aufgrund der hohen Speichernutzung, die es mit dem aktuellen Terminalpuffer-Design einführen wird, irgendwie blockiert. Es wird mehr Aufmerksamkeit bekommen, wenn #791 uns ein effizienteres Pufferlayout gebracht hat.

@rfgamaral einfach - Ich arbeite täglich auf vielen, vielen verschiedenen Unix-/Linux-Servern auf sehr großen Unternehmenssystemen mit vielen Microservices, und es ist störend, keine anständige Farbunterstützung im Haupthost zu haben. Es ist schmerzhaft, damit umzugehen, dass die Farben nicht gleich sind, egal ob ich Rhel, Centos oder Debian verwende. Wenn ich mich hinsetze, um einem jr- oder Peer-Entwickler unter Windows zu helfen, muss ich auch den Kontext wechseln, wenn die Dinge nicht einheitlich funktionieren. Ich bin jedoch sehr beeindruckt, wie schnell wsl mit fast monatlichen Verbesserungen und VS Code so schnell gekommen ist, es ist herausragend.

@jerch Danke für das Update, werde geduldig warten, bis #791 ausgearbeitet ist...

Freue mich auch sehr darauf.

Denken Sie daran, dass JavaScript-Zahlen genaue ganze Zahlen bis zu 53 Bit darstellen können. Sie haben also 21 Bit zusätzlich zu den 32 "praktischen" Bits. Sie können ein bisschen "oder" durch einfaches Hinzufügen, wenn es nicht bereits eingestellt ist. Um die höherwertigen Bits zu lesen, dividieren Sie einfach durch eine geeignete Ganzzahl mit Zweierpotenz und verwenden Sie dann die regulären Bitoperationen.

Natürlich gibt es etwas mehr Overhead bei der Arbeit mit den höherwertigen Bits, aber bei modernen CPUs ist die Division durch Power-oder-zwei relativ billig - billiger als Speicherzugriffe.

Ich schlage vor, eine einzelne Zahl mit 50 Bit zu verwenden: jeweils 25 Bit für Vorder- und Hintergrund. Ein Bit, wenn gesetzt, zeigt an, dass wir eine "wahre" 24-Bit-Farbe verwenden; wenn nicht gesetzt, verwenden wir "logische" (themenorientierte) oder 8-Bit-Farben. Die Indikatorbits sollten die 2 niederwertigen Bits sein; Wenn nicht gesetzt, könnten die logischen 8-Bit-Farben in den nächsten 30 Bits liegen, daher verwenden wir nur die Bits 32-50, wenn wir tatsächlich True-Color verwenden.

@PerBothner Wir

Außerdem habe ich einige Tests/Berechnungen zu möglichen Layouts durchgeführt (siehe https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900). Lange Rede, kurzer Sinn – die Ideen drehen sich um den Kompromiss zwischen Speichereinsparung und Laufzeiteinbußen. Der Übergang zum typisierten Array hat bereits enorme Speichereinsparungen gebracht (umsetzt derzeit die zweite Idee von oben, obwohl die wahren Farbwerte noch nicht angewendet werden).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen