Turbo Vision 2.0 – die Neuauflage der Text-UI der 90er
(github.com/magiblot)- Open-Source-Port, der Borlands Text-UI-Framework aus den 90ern plattformübergreifend und mit Unicode-Unterstützung modernisiert
- Beim Erstellen von Terminal-Apps ist keine Behandlung von Terminal-Kompatibilität nötig – läuft mit demselben Code unter Linux, Windows und DOS
- Größenveränderbare überlappende Fenster, Pulldown-Menüs, Dialoge, Buttons, Scrollbars, Eingabefelder, Checkboxen, Radio-Buttons und weitere TUI-Widgets sind bereits integriert, sodass sie nicht selbst implementiert werden müssen
- Umfassende UTF-8-Unicode-Unterstützung — unter Beibehaltung der bestehenden
char-basierten API können CJK-Vollbreitenzeichen, kombinierende Zeichen und sogar Emojis verarbeitet werden; mit nur einer ZeilemoveStr()werden Multibyte-Scrolling und Abschneiden automatisch behandelt - Nutzt die UTF-8-
setlocale-Unterstützung von Microsoft RTL, sodass Code wiestd::ifstream f("コンピュータ.txt")auch unter Windows unverändert funktioniert - 24-Bit-True-Color-Unterstützung — von den bisherigen 16 Farben erweitert auf RGB, xterm-256 und Standard-Terminalfarben; wenn das Terminal dies nicht unterstützt, wird automatisch auf die nächstliegenden Farben quantisiert
- Unterstützt moderne Ein-/Ausgabe vollständig, darunter Mausrad, mittlere Maustaste, Dreifachklick, Bildschirmgrößen bis 32767 Zeilen/Spalten und Fenstergrößenänderungs-Events
- System-Clipboard-Integration standardmäßig eingebaut: Unter Windows/macOS funktioniert es direkt, und auch in entfernten SSH-Umgebungen sind Kopieren/Einfügen per X11-Forwarding oder OSC-52-Escape-Codes möglich
- Bestehender Turbo-Vision-Quellcode aus der Borland-C++-Ära kann mit minimalen Änderungen unverändert gebaut werden
- Unterstützung für das CMake-Build-System; mit vcpkg genügt eine Zeile
./vcpkg install tvisionfür die Installation, und bei Hinzufügen vonadd_subdirectoryals CMake-Submodul werden Abhängigkeiten automatisch verlinkt - C++14 oder höher,
libncurseswerforderlich / MIT-Lizenz
1 Kommentare
Hacker-News-Kommentare
Es freut mich wirklich sehr, dieses Repository auf der Startseite zu sehen, und ich baue gerade selbst einen Wrapper dafür.
Ich lasse Turbo Vision unter .NET auf macOS laufen, und das wirkt ziemlich magisch.
Ich stelle eine höherstufige API bereit, kapsle oder verbessere die ziemlich veraltete Palette-API und füge außerdem Layout hinzu.
Im Moment läuft noch viel Arbeit in einem privaten Repository, und ich feile ständig weiter daran – heute etwa an der Palette auf Basis der Surface, auf der ein Control liegt, morgen dann wieder an einem anderen Teil.
Es gibt noch einiges zu tun, etwa das Layout aufzuräumen und grundlegende Controls zu ergänzen, die aus heutiger Sicht fehlen.
Ich habe früher auch Terminal.Gui verwendet, aber wegen des Übergangs zu v2 war es ziemlich schwer, damit ohne Bugs zu arbeiten, und Claude hat auch sehr gut gezeigt, was man besser nicht tun sollte, wenn man eine TUI-Bibliothek baut, ohne echte Terminals zu berücksichtigen.
Deshalb hatte ich mir eine moderne Version von Turbo Vision gewünscht, und dann bin ich auf dieses Repository gestoßen. Als ich gesehen habe, dass sogar Unicode-Unterstützung eingebaut ist, war ich wirklich dankbar.
https://www.remobjects.com/elements/oxygene/
https://www.remobjects.com/elements/
Ich baue ebenfalls einen .NET-Wrapper, bin vermutlich aber noch nicht so weit. Ich möchte die Windows-Forms-API so weit wie möglich nachbilden und sogar einen Drag-and-drop-TUI-Designer einbauen.
Ein Beispiel gibt es hier: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
Den Großteil der kniffligen Integrationsarbeit auf der C++-Seite habe ich hier erledigt: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
Ich exportiere einfache C-Funktionen, die per P/Invoke aufgerufen werden können, sodass sich die C#-Seite hauptsächlich auf die Strukturierung der Klassen konzentrieren kann.
Anfangs wollte ich unbedingt, dass alles, was in C++ möglich ist, auch in C# möglich sein muss. Das wurde aber viel zu komplex, und ich ging sogar so weit, C++-Objekte per placement new in C#-Buffer zu legen, also praktisch C++-Klassen von C# aus zu erben – da ist das Design dann kollabiert.
Am Ende bin ich zu einem direkteren Ansatz mit weniger Flexibilität, aber deutlich mehr Einfachheit gewechselt, und die Flexibilität habe ich auf die C#-Seite verlagert.
Mich würde interessieren, wie dein P/Invoke-System aufgebaut ist.
Vermutlich hat mich das davor bewahrt, mich an aussichtslosen Projekten zu versuchen, etwa Apps für GEOS zu bauen oder einem Ein-Personen-Hurd-Team beizutreten.
Ich habe zwar Terminal.Gui genutzt, fühlte mich aber mehr zu TV hingezogen und hatte deshalb über einen Wrapper nachgedacht. Wenn er veröffentlicht wird, würde ich ihn wirklich gern sehen.
Meine Programmierkarriere begann buchstäblich in den 90ern im Müllcontainer.
Ich habe ein weggeworfenes Turbo-Vision-Buch gefunden und mich sofort in die bläuliche TUI verliebt, die damals jeder bauen konnte.
Die ursprüngliche Version war in Turbo Pascal 6 enthalten, die C++-Portierung kam später.
Man kann das also als einen modernen Port eines Ports verstehen.
Bei Borland war das bei anderen Frameworks ähnlich: Auch OWL kam ursprünglich zuerst von Turbo Pascal for Windows 1.5, und ein großer Teil der Werkzeuge von C++ Builder war in Wirklichkeit in Delphi geschrieben.
Object Pascal aus Turbo Pascal 5.5 und dann Turbo Vision aus Version 6 waren mein Einstieg in OOP, und ich hatte Glück, dass ich genau auf diesem Weg hineingekommen bin.
Selbst in einer Umgebung wie MS-DOS konnte man die Vorteile von OOP und den Framework-Gedanken von Turbo Vision richtig gut lernen.
Als Borland Turbo Pascal, Turbo C++, TurboVision herausbrachte, fühlte es sich an, als würde sich ein ganzes Universum an Möglichkeiten öffnen.
Die Compiler waren hervorragend, und die Handbücher waren Kunstwerke. Ich wünschte, ich hätte diese Bücher noch.
Das ist einfach kulturelles Erbe.
Anfang der 90er habe ich mir C/C++ fast ausschließlich autodidaktisch beigebracht, nur mit dem Stapel Borland-Bücher, der mit Turbo C++ mitkam. Heute kann ich mir kaum noch vorstellen, dass jemand allein durch das Lesen von Referenzbüchern so lernt.
Bei neuen TUI-Frameworks hatte ich immer das Gefühl, dass irgendetwas fehlt, und jetzt will ich es noch einmal einsetzen, um zu sehen, ob das nur Nostalgie war.
Ich werde es in mein nächstes Tool einbauen und möchte den Machern großen Applaus zollen.
Abgesehen von GW-BASIC und MS-DOS war alles von Borland: Turbo BASIC, Turbo Pascal, Turbo C++ für MS-DOS und Windows 3.x, Turbo Vision, OWL.
VC++ habe ich erst ungefähr ab Version 5 benutzt, und MFC wirkte im Vergleich zu Borlands Produkten immer viel zu fade.
Selbst heute gibt es nur wenig, das wirklich an die RAD-Fähigkeiten von C++ Builder herankommt, und sogar .NET hat ziemlich lange gebraucht, um die Geschichte rund um Delphi-artiges Low-Level-Coding und AOT in den Griff zu bekommen.
Man sollte Go-, C++- und Rust-Entwicklern jeweils ein paar Exemplare von Turbo Pascal 7 für MS-DOS und einem aktuellen Delphi in die Hand drücken.
Turbo Vision 2.0 ist auch heute noch ziemlich brauchbar, deshalb habe ich es vor einem Jahr direkt für Prototyping verwendet.
Ich habe versucht, ein Turbo-Vision-Frontend für den LLDB-Debugger zu bauen, das wie Borlands Turbo Debugger funktioniert, und größtenteils hat das auch geklappt.
Es war erstaunlich, wie nahtlos es da weitermachte, wo 199x aufgehört hat, und ich konnte sogar Code von 1993 ohne große Probleme kompilieren und ausführen.
Für den eingebauten Editor gibt es auch eine bessere Scintilla-basierte Version mit Funktionen wie Syntax Highlighting, aber das, was ich daran umbauen wollte, hat nicht gut funktioniert, sodass ich wahrscheinlich den Autor um Hilfe bitten muss.
Was allerdings fehlt, ist Dokumentation im heutigen Sinn von kollektiv verfügbarem Wissen, sodass man nicht einfach Stack Overflow oder eine KI fragen kann. Ich musste auf die alte Art lernen: Beispielcode ansehen und ein paar Turbo-Vision-Bücher immer wieder lesen.
Manuelles Layout ist ziemlich umständlich, daher wäre ein automatisches Layout wie bei Qt schön, und einen Splitter vermisse ich auch, auch wenn er nicht schwer zu implementieren scheint.
Überraschend war für mich außerdem, wie klein und kompakt TV in Wirklichkeit ist. In den 90ern wirkte es riesig.
Insgesamt ist die Modernisierung wirklich gut gelungen, und ich mag das sehr.
Turbo Vision hatte ursprünglich sehr viel hochwertige Dokumentation.
Eher die heutige Welt leidet meiner Meinung nach an Dokumentationsmangel.
https://archive.org/details/bitsavers_borlandTurrogrammingGuide1992_25707423
Wenn ich all diese cmake-Anweisungen sehe, möchte ich fast in die Vergangenheit zurück.
In Turbo C oder Pascal hat man einfach F9 gedrückt, und es lief sofort.
Andererseits zeigt das für mich auch die Unfähigkeit unserer Toolchains.
Heutzutage sollte es reichen, auf einen Online-Compiler zu zeigen und sofort loszulegen oder etwas herunterzuladen, einen Ordner zu öffnen und es auszuführen. Stattdessen ist es eher zu einem Ritual als zu einem Werkzeug geworden.
./configure && make && make install sollte eigentlich immer noch der Goldstandard sein.
Das ist nur einer von mehreren Turbo-Vision-Ports/Klonen.
Für C++ gibt es auch das hier: https://github.com/kloczek/tvision
Die Version in FreePascal/Lazarus ist in Pascal geschrieben, und es gibt auch noch eine Rust-Version, die ein wenig vibe-coded wirkt: https://github.com/aovestdipaperino/turbo-vision-4-rust
Wenn man das im Terminal laufen lässt, geht ein Teil des eigentlichen Gefühls verloren, das die Maus im Textmodus-Bildschirm damals vermittelt hat.
Auf einem echten Textmodus-Bildschirm sah sie nicht wie ein Mauszeiger aus, sondern eher wie ein gelber Block, den man mit der Maus bewegt hat.
Ich frage mich, ob das jemand im hochauflösenden Linux-Textmodus mit GPM ausprobiert hat.
Es wurde einfach die Farbe der überlagerten Zelle invertiert, und weil das Hauptfenster, das den größten Teil des Bildschirms füllte, meist dunkelblau war, sah das Ergebnis oft wie ein hellgelber Block aus.
Ich empfehle die aktuelle Wookash podcast-Folge über Chuck Jazdzewski.
Er war Mitglied des ursprünglichen Teams hinter Turbo Vision, und es geht darin auch viel um das gesamte Ökosystem.
Ich will immer noch lieber das echte Turbo Vision, also die Pascal-Version, statt der C++-Version.
Die C++-Version fühlt sich letztlich eher wie eine Übertragung der Pascal-Version an.
In Pascal ist zum Beispiel
usesein Schlüsselwort, während das Einbinden von Modulen per#defineirgendwie wie ein Hack wirkt.Vielleicht ist das heute kein großer Unterschied mehr, aber trotzdem.
Auch die Textmodus-IDE verwendet Free Vision.
https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
Der entscheidende Unterschied ist allerdings, dass Free Vision und Turbo Vision nicht Delphis
class, sondern denobject-Typ aus Turbo Pascal 5.5 verwenden.Mit
classlassen sich dank RTTI Dinge wie automatische Serialisierung leicht implementieren, währendobjectso etwas nicht hat. Um verschiedene Typen zur Laufzeit zu unterscheiden, muss man daher manuelle Serialisierung betreiben, etwa indem man den VMT-Zeiger registriert, der an einem festen Offset im Objektzeiger liegt.Free Pascal hat
objectzwar um Komfortfunktionen wie private/protected/public und properties erweitert, aber Free Vision nutzt diese Erweiterungen nicht, weil es die ursprüngliche Turbo-Vision-API nachbilden soll.