9 ポイント 投稿者 GN⁺ 3 일 전 | 1件のコメント | WhatsAppで共有
  • 古典的なテキストUIフレームワークをLinuxとWindowsで再活用できるよう移植し、UTF-8と拡張色を含む共通の開発基盤を提供する
  • 既存のTurbo Visionアプリのソースコードレベル互換性を最大限維持しつつ、charベースのAPIを継続利用して、プラットフォームごとのターミナル差異をライブラリ内部で吸収する
  • Unicode入力と表示をフレームワーク全体に統合し、2セル幅文字、結合文字、マルチバイトのショートカットキー、UTF-8ベースの編集と描画をあわせて処理できる
  • 重なり合うウィンドウ、メニュー、ダイアログ、入力欄、スクロールバーといった基本ウィジェットを備え、イベントループ、タイマー、クリップボード、マウスホイール、リサイズ、大容量ファイル編集といった現代的な動作もサポートする
  • 16色中心の過去APIを超えて24ビットカラー、xterm-256パレット、システムクリップボード、複数のコンソール環境対応までをまとめ、古いTUIコードと現代のターミナル環境をつなぐ基盤になる

プロジェクトの性格と中核方針

  • Turbo Vision 2.0のモダンな移植版であり、古典的なテキストUIフレームワークをLinuxとWindowsで再活用できるようにしつつ、UTF-8と拡張色まで取り込んでいる
  • 当初はLinux対応の追加と既存DOS/Windows動作の維持、古いTurbo Visionアプリのソースコードレベル互換性の保持に重点を置いていた
    • この互換性のため、一部のBorland C++ RTL関数も直接実装している
  • 2020年7〜8月の間に既存構造の中へ完全なUnicode対応を統合し、その過程で Turbo テキストエディタも作成した
  • アプリケーションがターミナル機能差や直接的なターミナルI/O処理を迂回しないようラップし、プラットフォーム差異をライブラリ側で吸収する
  • LinuxとWindowsで同じコードによりテキストUIを書くことに焦点を当て、wchar_tTCHARではなく引き続きcharベースのAPIを維持している

なぜ有用か

  • ウィジェットクラスを多数提供し、サイズ変更可能な重なり合うウィンドウ、プルダウンメニュー、ダイアログ、ボタン、スクロールバー、入力欄、チェックボックス、ラジオボタンなどをすぐに使える
  • 独自ウィジェットを作る場合でも、イベントディスパッチや全角Unicode文字表示といった共通処理を書き直す負担を減らせる
  • 各環境でできる限り同じ結果が出るように処理する
    • Linuxコンソールで明るい背景色がblink属性に依存する場合も、ライブラリが代わりに処理してくれる
  • Microsoft RTLのsetlocale UTF-8対応を活用し、Windowsでも std::ifstream f("コンピュータ.txt"); のようなコードが意図どおり動作できる
    • WindowsではRTLがファイル名をシステムエンコーディングへ即座に変換する

Unicode設計とテキスト処理

  • UTF-8を入力と表示の基本エンコーディングとして採用している
    • 既存のchar *データ型と互換性があり、ターミナルI/Oエンコーディングと同じなので不要な変換を減らせる
    • UTF-8 Everywhere Manifesto の方向性とも一致する
  • Borland C++でビルドする場合はUnicodeをサポートしないが、API拡張はエンコーディング非依存コードを書けるよう設計されている
  • KeyDownEventには既存のcharScan.charCodeに加えてtext[4]textLengthが追加され、UTF-8入力バイト列を直接渡す
    • charScan.charCodeには下位互換性のため今もCP437基準の文字が入る
    • getText()でstring viewを受け取って使う方式が推奨される
  • 入力例はUnicodeと旧来コードがともに動作する仕組みをそのまま示している
    • ñ を入力すると charCode=164 ('ñ'), text={'\xC3','\xB1'}, textLength=2 になる
    • を入力するとCP437にないため keyCode=0x0, charCode=0, text={'\xE2','\x82','\xAC'}, textLength=3 になる
    • ショートカットキー入力時は textLength=0 で空になる
  • TScreenCellはUTF-8コードポイントと太字、下線、斜体といった拡張属性を保持できる
    • ASCII制御文字はコードページ文字のように扱われる
    • 有効なUTF-8はそのまま表示され、無効なUTF-8はコードページ文字として扱われる
    • 拡張ASCIIとUTF-8を混在できるため下位互換性には有利だが、予期しない結果が生じることもある
  • 2セル幅文字結合文字も個別に処理する
    • 結合文字は前の文字の上に重ねて表示される
    • ZERO WIDTH JOINER U+200D は常に省略される
    • ターミナルがwcwidth基準の文字幅を尊重すれば、目立つ描画崩れはほとんどない
    • Wide character display で例を確認できる

Unicode APIと標準ビューのサポート

  • Unicode対応の描画API

    • TDrawBuffer::moveChar, putCharchar cコードページ文字として扱う
    • moveStr, moveCStrTStringView を受け取り、Unicodeの規則で文字列を処理する
      • maxStrWidth はバイト数ではなく カラム数 基準
      • strIndent もバイトではなく カラム数 基準なので横スクロールに使える
      • 戻り値はコピーされたテキストの 表示幅
    • moveBufTStringView 導入前に null-terminated ではない文字列を処理していた関数のため維持されている
    • cstrlen(TStringView s)~ を除いた表示長を、strwidth(TStringView s)~ を含む表示長を返す
  • draw() の単純化とバグ削減

    • 従来の TFileViewer::draw() は部分文字列を一時バッファにコピーしてから moveStr を呼び出していたが、この方式には buffer overrun の危険とマルチバイト境界の問題があった
    • 修正後は b.moveStr(0, p, c, size.x, delta.x); の1行で処理し、中間コピーをなくした
      • delta.x をカラム基準でそのまま適用できる
      • 最大 size.x カラム分だけコピーするため、バイト数と境界条件を直接計算する必要が減る
  • Unicode表示をサポートする標準ビュー

  • Unicode入力まで処理するビュー

    • TInputLine, cb489d42, TEditor, TMenuView のショートカットキー では Unicodeユーザー入力 まで処理する
    • TEditor インスタンスはデフォルトで UTF-8モード であり、Ctrl+P で single-byte モードに切り替え可能
    • この切り替えはドキュメント内容を変えず、表示方式入力エンコーディング だけを変更する
    • TStatusLine, TButton などの 強調されたキーボードショートカット には対応していない
  • メニューとステータスラインの多言語文字列

    • ~Ñ~ello, 階~毎~料入報最..., 五劫~の~擦り切れ, העברית ~א~ינטרנט, ~Alt-Ç~ Exit のような文字列をメニューとステータスラインでそのまま使える
    • 結果画面は Unicode Hello で確認できる

プラットフォーム別の動作モデル

  • Unix

    • Ncurses ベースのターミナル対応を使用
    • X10、SGR マウスエンコーディング、xterm の modifyOtherKeys、Paul Evans の fixterms、Kitty の keyboard protocol、WSL Conpty の win32-input-modefar2l、Linux コンソールの TIOCLINUX 修飾子と GPM マウスに対応
    • プログラムが異常終了する前にターミナル状態を復元する カスタムシグナルハンドラー を備える
    • stderr が tty の場合、画面破損を防ぐためバッファに保存し、終了時または一時停止時に出力
      • バッファサイズに制限があるため、いっぱいになると stderr への書き込みが失敗する場合がある
      • すべて保持するには 2> リダイレクトを推奨
    • TERMCOLORTERMESCDELAYTVISION_USE_STDIO 環境変数を読み取る
      • COLORTERM=truecolor または 24bit であれば 24 ビットカラーを前提とする
      • ESCDELAY のデフォルト値は 10ms
      • TVISION_USE_STDIO が空でなければ /dev/tty の代わりに stdinstdout で I/O を行う
  • Windows

    • Win32 Console API のみに対応
    • これをサポートしないターミナルエミュレーターでは、別個のコンソールウィンドウを自動で開く
    • アプリケーションのレイアウトはコンソールバッファではなく コンソールウィンドウサイズ を基準とし、終了時または一時停止時にコンソールバッファを復元する
    • Borland C++ でない場合は、起動時にコンソールコードページを UTF-8 に変更し、終了時に復元する
    • Microsoft C ランタイムも UTF-8 モードに切り替え、開発者が wchar_t 系を直接使う必要を減らす
    • レガシーモードとビットマップフォントの組み合わせでは Unicode 表示が崩れることがあり、これを検出すると Consolas または Lucida Console へのフォント変更を試みる
      • 例は photo で確認できる
  • 共通の動作改善

    • 24 ビットカラーstdin/stdout/stderr リダイレクトとの共存、32 ビット help ファイル互換性を提供
    • TVISION_MAX_FPS 環境変数で最大更新レートを制御
      • デフォルト値は 60
      • 0 は制限を無効化
      • -1THardwareInfo::screenWrite 呼び出しごとに即時描画させる
    • 中ボタン、マウスホイール、最大 32767 行/列 の画面サイズ、リサイズイベントに対応
    • ウィンドウは左下隅からもサイズ変更でき、中ボタンで空白領域をつかんでドラッグできる
    • メニューは親項目を再クリックして閉じられ、スクロールバーはドラッグ中のページスクロールとホイール入力に反応する
    • TInputLine はフォーカス移動時に不要なテキストスクロールを行わない
    • TFileViewerTEditorLF 改行 をサポートし、TEditor は保存時に既存の改行コードを維持し、新規ファイルではデフォルトで CRLF を使う
    • TEditor には右クリックメニュー、中ボタンドラッグスクロール、単語単位削除キー、Home キー改善、64 KiB 超のファイル対応まで含まれる
    • tvdemo にはイベントビューアアプレットと背景パターン変更オプションが含まれる

イベントループと API の変更

  • 画面書き込みのバッファリング を使用し、通常はアクティブなイベントループ 1 回ごとに 1 回ターミナルへ送信する
  • ビジーループで即時更新が必要な場合は TScreen::flushScreen() を呼び出せる
  • TEventQueue::waitForEvents(int timeoutMs) は入力イベントを待機し、待機中も TScreen::flushScreen() によって画面更新を行う
  • TProgram::getEvent() はデフォルト値 20eventTimeoutMs でこれを呼び出し、100% CPU のビジーループ を避ける
  • TEventQueue::wakeUp() は別スレッドからイベントループを起こす thread-safe なメソッド
  • TView::getEvent(TEvent &, int timeoutMs) により、ビュー単位のタイムアウト待機を設定できる
  • setTimerkillTimer が追加され、タイマー満了時に evBroadcastcmTimerExpired を発生させる
    • periodMs が負数ならワンショットタイマーとして自動的にクリーンアップされる
    • タイマーイベントは TProgram::idle() で生成され、キーボードまたはマウスイベントがないときにのみ処理される
  • TDrawBuffer はもはや固定長配列ではなく、範囲外アクセスを防ぐ
  • TRectmovegrowintersectUnionTRect& を返し、チェーン呼び出し が可能
  • TApplicationdosShell()cascade()tile() を標準提供し、cmDosShellcmCascadecmTile をデフォルト処理する
  • TStringViewTSpan<T>TDrawSurfaceTSurfaceViewTClipboard などの型が追加された
  • THardwareInfoTScreenTEventQueuemain より前ではなく、最初の TApplication 生成時に初期化される
  • 入力拡張も含まれる
    • evMouseWheelmwUpmwDownmwLeftmwRight
    • mbMiddleButtonmeTripleClick
    • evMouseUp.buttons に解放されたボタン情報を保持
    • hotKeyStrgetAltCharStrgetCtrlCharStr により マルチバイトショートカット を実装可能
    • TKey により Shift+Alt+Up のような新しいキー組み合わせを定義可能
    • TInputLineilMaxBytesilMaxWidthilMaxCharslimitMode をサポート

クリップボード連携

  • システムクリップボード統合

    • 従来は TEditor::clipboard 静的メンバーによる 内部クリップボード のみが存在し、これを利用できるのは TEditor だけだった
    • 新しい TClipboard クラスで システムクリップボード にアクセスし、アクセスできない場合は内部クリップボードにフォールバックする
  • 対応環境

    • Windows、WSL、macOS では標準で対応
    • macOS を除く Unix では外部依存が必要
    • リモート実行では、ssh -X の X11 forwarding、far2lputty4far2lOSC 52 対応ターミナルで動作可能
    • 一部の他のターミナルは コピーのみ対応
    • ターミナルエミュレーターの Ctrl+Shift+VCmd+V による貼り付けは、別途常に可能
  • API と貼り付け処理

    • <tvision/tv.h> をインクルードする前に Uses_TClipboard を定義すると TClipboard を利用できる
    • setText(TStringView text) はシステムクリップボードの内容を設定し、アクセスできない場合は内部クリップボードを使う
    • requestText() はシステムクリップボードの内容を 非同期で要求 し、その後通常の evKeyDown イベント形式で受け取る
    • 貼り付けテキストは keyDown.controlKeyStatekbPaste フラグ で通常のキー入力と区別できる
    • 長い貼り付けが数千回のキー入力のように処理される非効率を減らすため、TView::textEvent(...) が追加された
      • 連続する evKeyDown テキストをユーザーバッファにまとめて読み取る
      • もはやテキストでなくなった場合は putEvent() で次のループに渡す
  • 標準コマンド連携

    • TEditorTInputLinecmCutcmCopycmPaste コマンドに反応する
    • アプリケーションはステータスバーなどで kbCtrlXkbCtrlCkbCtrlV を各コマンドに接続する必要がある
    • フォーカスと選択状態に応じて、関連コマンドを自動的に有効化または無効化する

拡張カラーモデルと互換性

  • Turbo Vision API は従来の 16 色を超える 拡張カラー をサポートする
    • 4 ビット BIOS color attributes
    • 24 ビット RGB
    • 8 ビット xterm-256color palette index
    • terminal default color
  • ターミナルが特定の色形式をサポートしていない場合、Turbo Vision が 量子化 して表示する
  • モダンなプラットフォームでは uchar の代わりに TColorAttrushort の代わりに TAttrPair を導入
    • TPaletteTColorAttr 配列を使用する
    • TView::mapColorvirtual となり、階層型パレットシステムを迂回した色指定が可能になった
  • TColorBIOSTColorRGBTColorXTermTColorDesired により色表現の階層を分ける
    • TColorAttrforegroundbackgroundstyle ビットマスクを持つ
    • スタイルには slBoldslItalicslUnderlineslBlinkslReverseslStrike を含む
    • slReverse は信頼性が低いため、reverseAttribute(TColorAttr attr) の使用が推奨される
  • TView で拡張カラーを使う方法は 3 つある
    • mapColor をオーバーライドしてインデックスごとに ハードコード する
    • draw()TDrawBuffer直接 TColorAttr を渡す
    • アプリケーション パレット自体を変更 する
  • TScreen::screenMode でディスプレイ能力を公開する
    • smMono は monocolor
    • smBW80 は grayscale
    • smCO80 は少なくとも 16 色
    • smColor256 は少なくとも 256 色
    • smColorHigh はそれ以上の色、たとえば 24 ビットカラーを意味する
  • 下位互換性は #ifdef のない共通 API の維持に合わせて設計されている
    • Borland C++ では TColorAttrTAttrPair はそれぞれ ucharushort の typedef になる
    • モダンなプラットフォームでは従来の ucharushort の位置を置き換えられる
    • レガシーコードはそのままコンパイルできるが、non-BIOS 色属性ucharushort に暗黙変換された時点で失われる可能性がある
  • draw メソッドで ushort をパレットインデックス対と色属性対の両方に使っていたコードはそのまま動作するが、拡張カラーを活かすには変数宣言を ushort から TAttrPair に変えればよい
  • TColorDialog は再設計されていないため、ランタイムの 拡張カラー選択器 としては利用できない

ビルド、配布、統合

  • Linux と Unix 系

    • CMake と GCC/Clang により、静的ライブラリ libtvision.a をビルド可能
    • hellotvdemotvedittvdirmmenupalettetvhc Help Compiler もあわせて生成される
    • 要件は C++14 対応コンパイラlibncursesw、任意の libgpm
    • ランタイムのクリップボード連携には xselxclipwl-clipboard が使われる
    • 一部の環境では -ltinfow が必要な場合があり、そうでないと実行時に segmentation fault が発生することがある
      • 関連 issue: #11
  • Windows とその他のツールチェーン

    • MSVC ビルドでは、対象アーキテクチャごとに個別のビルドディレクトリを使い、成果物は tvision.lib とサンプルアプリとして生成される
    • TV_USE_STATIC_RTL オプションで Microsoft ランタイムの静的リンクが可能
    • /MT/MD、デバッグ版と非デバッグ版のバイナリは相互に混在リンクできない
    • <tvision/tv.h> を使うには /permissive-/Zc:__cplusplus フラグが必要で、CMake のサブモジュール方式なら自動で有効化される
    • 適切な MSVC バージョンと設定であれば Windows XP も可能とされている
    • MinGW は Linux と同様に CMake でビルドし、コンパイラが対応していれば Windows XP 以降で実行可能
    • Borland C++ でも DOS または Windows 向けライブラリのビルドは可能だが、Unicode はサポートしない
    • Borland C++ 環境では winevdm の使用が代替案として示されている
  • プロジェクト統合方法と配布状況

    • CMake では find_package(tvision CONFIG) または add_subdirectory(tvision) の 2 方式を提供
    • どちらの方式でも include パスと Ncurses、GPM など必要なリンクを自動処理する
    • vcpkgtvision ポートがある
    • 現時点では stable release はなく、最新コミット基準でアップグレード中に見つかった問題の報告が推奨されている
    • Unix 系ではデモアプリを自分でビルドする必要がある
    • Windows バイナリは Actions で提供される
      • examples-dos32.zip: Borland C++ ビルドの 32 ビット実行ファイル、Unicode 非対応
      • examples-x86.zip: MSVC ビルドの 32 ビット実行ファイル、Windows Vista 以降が必要
      • examples-x64.zip: MSVC ビルドの 64 ビット実行ファイル、x64 Windows Vista 以降が必要

サンプル、ドキュメント、活用事例

  • 入門用として Turbo Vision For C++ User's Guide が推奨されている
  • 基礎を身につけた後は、Turbo Vision 2.0 Programming Guide も参考にできる
  • サンプルとして hellotvdemotveditpalette などを提供
  • スクリーンショット集は here で見られる
  • 活用中のアプリケーションとして、以下が挙げられている
    • Turbo: proof-of-concept のテキストエディタ
    • tvterm: proof-of-concept のターミナルエミュレータ
    • TMBASIC: コンソールアプリケーション作成のためのプログラミング言語

1件のコメント

 
GN⁺ 3 일 전
Hacker Newsのコメント
  • このリポジトリがフロントページに載っているのを見て本当にうれしくなったし、今はこのリポジトリ向けのwrapperを自分で作っている
    .Net上でmacOS向けにTurbo Visionを動かしているのだが、かなり魔法のような感覚がある
    より高水準のAPIを提供し、かなり古めかしいpalette APIもラップまたは改善し、layoutも追加しているところだ
    まだ非公開リポジトリで鋭意作業中で、今日はコントロールが置かれたsurface基準でpaletteを決め、明日は別の部分を整えるという感じで継続的に手を入れている
    layoutの整理や、今の基準で不足している基本コントロールの追加など、やることはまだ残っている
    以前Terminal.Guiも使ってみたが、v2への移行中だからか、バグなしで扱うのはかなり難しかったし、Claudeも実際のターミナルを考慮せずにTUIライブラリを作ると何をしてはいけないかをよく示していた
    だから現代版Turbo Visionがあればいいのにと思っていたところでこのリポジトリを見つけ、Unicode対応まで入っているのを見て本当にありがたかった

    • OxygeneはRemObjectsのElements製品群の一部なので、Pascal系のOxygeneだけでなく、複数の人気言語を混在させながらWindows、macOS、Linux、Androidなどへ展開できる
      https://www.remobjects.com/elements/oxygene/
      https://www.remobjects.com/elements/
    • 自分もこのtvisionポートで作業してみたが、新しいTUIフレームワークを触るたびに、結局Turbo Visionのほうが優れていると感じる
      私も.NET wrapperを作っていて、たぶん進捗はそこまでではないが、Windows Forms APIをできるだけ近く再現しつつ、drag-and-dropのTUIデザイナーまで入れたいと思っている
      例はこちら: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
      C++側の厄介な統合作業の大半はこちらで処理した: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
      P/Invokeで呼べるようにシンプルなC関数をexportしておき、C#側は主にクラス構造化に集中できるようにした
      最初はC++で可能なことはすべてC#でも可能であるべきだと押し通したが、あまりに複雑になり、placement newでC++オブジェクトをC#バッファ内に置いて、実質的にC#側でC++クラスを継承するようなレベルまで行ったところで設計が破綻した
      結局、より直接的で柔軟性は低いがはるかに単純なアプローチに切り替え、柔軟性はC#側に持たせることにした
      あなたのP/Invokeシステムがどう構成されているのか気になる
    • このTVライブラリを触るとノスタルジーをしっかり刺激されて楽しい
      おかげでGEOS向けアプリを作るとか、1人Hurdチームに入るとかいう無駄な試みをせずに済んでいる気がする
    • 私も同じことをやってみたかった
      Terminal.Guiも使ってみたが、TVのほうが魅力的でwrapperを考えていたので、公開されたらぜひ見てみたい
  • 私のプログラミング歴は文字どおり90年代にゴミ箱から始まった
    誰かが捨てたTurbo Visionの本を拾い、誰でも作れた青みがかったTUIにすぐ夢中になった

  • 元のバージョンはTurbo Pascal 6に含まれていて、C++ポートは後から出た
    だからこれはポートの現代的ポートと見ていい
    Borlandは他のフレームワークでも似たようなことをしていて、OWLももともとはTurbo Pascal for Windows 1.5のほうが先だったし、C++ Builderのツールのかなりの部分も実際にはDelphiで書かれていた
    Turbo Pascal 5.5のObject Pascal、そして6のTurbo Visionが私のOOP入門だったが、その道に入れたのは幸運だったと思う
    MS-DOSのような環境でも、OOPとTurbo Visionがもたらすフレームワークの利点をしっかり学べた

    • 面白いことに、Free Visionは一時パブリックドメインとして公開されたC++版を誰かが手作業で翻訳し、再びObject/Free Pascalへ移植した結果生まれたものだ
    • OWLは本当に時代を先取りしていた
  • BorlandがTurbo Pascal、Turbo C++、TurboVisionを出してきたとき、可能性の宇宙が一気に広がったように感じた
    コンパイラ性能も素晴らしく、マニュアルは芸術品のようで、あの本を今でも持っていられたらと思う
    これは単なる文化的宝物だ

    • あのマニュアルは本当にすごかった
      90年代初頭にC/C++をほぼTurbo C++付属のBorland本の山だけ読んで独学したが、今では参考書だけ読んでそうやって学ぶ場面を想像することすら難しい
    • Turbo Visionは長い間、自分にとっての黄金標準のような存在だった
      新しいTUIフレームワークはいつも何かが足りない感じがしていたし、今これをまた使ってみて、それが単なるノスタルジーだったのか確かめようと思っている
      次のツールに組み込む予定で、作った人たちには大きな拍手を送りたい
    • Borland一色だった時代があった
      GW-BASICとMS-DOSを除けば、Turbo BASIC、Turbo Pascal、Turbo C++ for MS-DOS and Windows 3.x、Turbo Vision、OWLまで全部Borlandだった
      VC++は5あたりから使ったが、MFCはBorland製品に比べるといつもあまりに味気なく感じられた
      今でもC++ BuilderのRAD能力に本当に追いつけているものは少なく、.NETもDelphiのような低レベルコーディングとAOTのストーリーを整理するのにかなり長い時間がかかった
      Go、C++、Rustの開発者にはMS-DOS向けTurbo Pascal 7と最新のDelphiを何部かずつ渡すべきだと思う
  • Turbo Vision 2.0は今でもかなり実用的で、1年前にプロトタイプ作業で実際に使ってみた
    LLDBデバッガ向けのTurbo Visionフロントエンドを作り、BorlandのTurbo Debuggerのように動かそうとしたが、大半は思いどおりにいった
    199x年で止まった場所をそのまま引き継いだようで驚かされたし、1993年のコードも大きな問題なくコンパイルして実行できた
    内蔵エディタにもScintillaベースのより良い版があって、syntax highlightingのような機能も入っているが、私が改造しようとしていた部分はうまくいかず、たぶん作者に助けを求める必要がありそうだ
    ただ、現代的な共有知としての意味でのドキュメントは不足していて、Stack OverflowやAIに尋ねるのは難しく、サンプルコードを見て学び、Turbo Visionの本を何冊も読み返す昔ながらのやり方で進めるしかなかった
    手動layoutはかなり面倒なので、Qtのような自動layoutがあるといいし、splitterも少し恋しいが、実装自体は難しくなさそうだ
    もうひとつ驚いたのは、TVが実際にはかなり小さくコンパクトだという点だ。90年代にはものすごく巨大に感じていた
    全体として現代化の作業は本当によくできていて、私はこれをとても気に入っている

  • cmakeディレクティブが山ほどあるのを見ると、つい昔に戻りたくなる
    Turbo CやPascalではF9を押せばすぐ動いたのに
    一方で、これは私たちのツールチェーンの無能さも示していると感じる
    今の時代ならオンラインコンパイラをひとつ示してすぐ実行するか、ダウンロードしてフォルダをひとつ開いて実行する程度で済むべきなのに、ツールというより儀式の手順になってしまっている

    • 現代Unixでのソフトウェアコンパイルは、かつてすでに解決済みの問題だった
      ./configure && make && make installこそ、今でもgold standardであるべきだ
  • これはTurbo Visionポート/クローンのひとつにすぎない
    C++側にはこれもある: https://github.com/kloczek/tvision
    FreePascal/Lazarusに入っている版はPascalで書かれていて、Rust版もひとつあるが、少しvibe-codedっぽく見える: https://github.com/aovestdipaperino/turbo-vision-4-rust

  • ターミナルでこれを動かすと、本来のテキストモード画面のマウスが持っていた肝心の感覚が少し失われる
    本物のテキストモード画面では、マウスポインタではなく、マウスで動く黄色いブロックのように見えた
    高解像度LinuxテキストモードでGPMを使って動かしてみた人がいるのか気になる

    • 本質的に黄色だったわけではない
      下のセルの色を反転して表示する方式で、画面の大半を埋めるメインウィンドウが濃い青だったため、結果として明るい黄色のブロックのように見えることが多かった
  • 最近のWookash podcastでChuck Jazdzewskiを扱った回を勧めたい
    もともとTurbo Visionを作ったチームの一員で、そのエコシステム全体の話もたくさん出てくる

  • 私はいまだにC++版より本物のTurbo Vision、つまりPascal版のほうを求めている
    C++版は結局、Pascal版を移したものに近く感じられる
    たとえばPascalではusesがキーワードなのに、#defineでモジュールをincludeする方式はどうしてもハックっぽく感じる
    まあ今となっては大きな違いではないかもしれないが

    • Free Pascalに含まれているFree Visionが事実上その役割を果たしている
      テキストモードIDEもFree Visionを使っている
      https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
      ただし大きな違いは、Free VisionとTurbo VisionがDelphiのclassではなく、Turbo Pascal 5.5時代のobject型を使っている点だ
      classならRTTIのおかげで自動シリアライズのようなものを実装しやすいが、objectにはそれがないので、異なる型を実行時に区別するには、オブジェクトポインタの固定オフセットにあるVMTポインタを登録するような形で手動シリアライズを行う必要がある
      Free Pascalはobjectにprivate/protected/publicやpropertyのような便利機能を少し追加しているが、Free Visionは元のTurbo Vision APIを実装するため、そうした拡張は使っていない