世界を動かす技術を、日本語で。

Show HN: Tattoy – テキストベースのターミナルコンポジタ

概要

  • Tattoy はターミナルに視覚効果を追加するフレームワーク
  • GPUシェーダー やライブ更新される スクロールバックミニマップ を搭載
  • 既存のシェルやプロンプトと シームレスに連携
  • 自動コントラスト調整 による可読性の向上
  • プラグイン によるカスタマイズ性と拡張性

Tattoy:ターミナルに美しい視覚効果を

  • Tattoy は、ターミナルに アイキャッチな視覚効果 を追加するためのフレームワーク
  • 純粋なテキストベース のため、 True Color 対応のターミナルエミュレータで動作
  • UTF8ハーフブロック(▀、▄) でグラフィックを表現
  • 既存のシェル・テーマ・プロンプト と共存可能
  • 効果の 即時切り替え が可能で、 コピー&ペースト も容易

GPUシェーダーのレンダリング

  • Tattoyの最大の特徴は GPUシェーダーの描画機能
  • Shader Toy の多くのシェーダーを 編集なしで実行 可能
  • Ghosttyシェーダー にも対応
  • テキストの位置を変えるシェーダー(例:CRTエミュレータ)は、ホストターミナルに依存するため効果が限定的

バックグラウンドでのセカンドターミナル表示

  • 任意のコマンドを 通常のターミナルの背景 として実行可能
  • 利用例
    • オーディオビジュアライザー
    • 動画背景
    • システムモニターグラフ
  • 背景ターミナルの 不透明度調整 機能

スクロールバックミニマップ

  • スクロールバック内容を ピクセル化 して表示する ライブミニマップ
  • nvimtopgituiなどの "alternate screen" 使用時も対応
  • 独自のスクロールバックバッファスクロールバー を提供

自動テキストコントラスト調整

  • ディレクトリ内のファイル表示で 読みにくい色 が発生する問題を解決
  • 24ビットRGBA値 を認識し、 コントラスト不足のテキスト色を自動調整
  • WCAG 2.1コントラストアルゴリズム を採用し、 アクセシビリティ を確保

プラグインによる拡張性

  • 任意の言語 でプラグイン作成が可能
  • ターミナル内容へ フルアクセス し、 UTF8ピクセルやテキスト の描画が可能
  • JSON(STDIN/STDOUT) によるプロトコル
  • 例:カーソルからテキストと連動した 煙エフェクト の表示

Tattoyの本質と今後の展望

  • 視覚効果による ターミナルの美的向上 が主目的
  • 低コントラスト問題 の根本的解決
  • 新しいターミナルプロトコルの実験基盤 としての役割
    • ANSIコードの代替プロトコルの ポリフィル
    • xwayland的存在 としてのTattoy
  • 詳細:https://tattoy.sh/news/an-end-to-terminal-ansi-codes/
  • アートプロジェクト的側面 も持つ、楽しさと美しさの追求

Hackerたちの意見

リポジトリリンク https://github.com/tattoy-org/tattoy

これすごい!公開してくれてありがとう、そして頑張ってね!

リリースプランからWindowsを追加して削除したみたいだけど、結局サポートされてるの?見た目はめっちゃいいね。

ありがとう。Windowsはサポートしてるよ。Windows TerminalとPowershellでテストしたからね。リリースプランからその問題を削除したのは、まだ全てのサブタスクが終わってないからなんだ。それに、Windowsユーザーからのフィードバックがあまりなかったのも理由かな。例えば、WindowsのVMでGPUパススルーをうまく動かせなかったから、シェーダーのテストもまだできてないんだ。

あなたが本当に欲しかったのは、VTEじゃなくてストリーミングSVGレンダラーだったみたいだね。そのアイデア、ちょっといいと思う。

どういう意味?実は、SixelやKittyの画像プロトコルみたいなターミナル画像プロトコルはあんまり好きじゃないんだ。テキストだけを使う制約を大事にしてるから。リアルなグラフィックスに踏み込むと、ターミナルの魂が失われる気がするんだよね。

見た目のためにcmatrixを動かすか、背景にhtopを使うかも。あと、スクリーンショットにリックロールも入ってるね。

Tattoyは独自のスクロールバックバッファを管理してるから(例えばtmuxみたいに)、独自のスクロールバーも提供できるんだ。これで二つの質問が浮かぶんだけど、全ての(GUI)ターミナルもそうなの?それと、Tattooの中でtmuxを使ったらどうなるの?ちなみに、ライトテーマの例ってある?

そうだね、どのGUIターミナルも自分のスクロールバックバッファを管理してるよ。Tattooやtmuxがそれぞれバッファを持ってるのは、彼らが基本的にターミナルエミュレーターだからなんだ。例えば、ターミナルエミュレーターが10個のtmuxペインを持ってたら、それぞれの履歴を見れるのは当然だよね。Tattooは自分のスクロールバックを管理してるけど、これは他のプロセスにプログラム的にスクロールバックを提供する唯一の方法なんだ。例えばミニマップとかね。面白いことに、Alacrittyは最初はスクロールバックをネイティブでサポートしてなかったんだ。tmuxみたいなマルチプレクサにその問題を任せたかったから。だから、ターミナルエミュレーターがスクロールバックをサポートしなくてもいい前例があるんだ。Tattooではtmuxがちゃんと動くはずだけど、気をつけてほしいのは、Tattooが入力を処理するから、スクロールとかのイベントがtmuxに届かないことがあるかもしれないってこと。その場合、Tattooが認識しないカスタムtmuxキー割り当てを作ることができるよ。それと、Tattooはtmuxがホストを制御する「オルタネートスクリーン」状態を認識することも覚えておいてね。そういう場合、Tattooはマウスのスクロールホイールみたいなスクロールイベントを基盤プロセスに転送するんだ。明るいテーマの例はまだないけど、基本的にはちゃんと動くはずだよ。

これめっちゃクールだね、試してみたいな。ターミナルのスクリーンショットを撮って、それを解析して本当の色のサポートを判断するってアイデアは確かに新しいけど、私にはうまくいかないんだ。デバッグフラグを有効にできるかな?今のところ、スクリーンショットは正しく撮れたけど(https://ibin.co/8kaRr8TIanv2.png)、その解析が「パレットの解析に失敗しました。」ってエラーで失敗してる。追記:トレースを有効にしたらこれが出たよ:https://paste.ee/p/ZyNxG9FK

ターミナルのスクリーンショットを撮って、それを解析して本当の色のサポートを判断するってアイデアは確かに新しい、 これをもっと良くする方法は、OSC 1 0 ; ? ST(前景色を問い合わせ)、OSC 1 1 ; ? ST(背景色)、次にOSC 4 ; {n} ; ? STを送ることだよ。ここで{n}はn番目のXTermカラー。詳しくはここを見てね:https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-O...

試してくれてありがとう。どうやらあなたのターミナルかスクリーンショッターが純粋な赤のマーカー列を忠実に描写してないみたいだね(これはパーサーのキャリブレーションに必要なんだ)。赤は#ff0000であるべきだけど、スクリーンショットは#ea3323を使ってる。進捗を追うためにGithubにイシューを作ったよ:https://github.com/tattoy-org/tattoy/issues/98 もっと詳細を追加してくれたらすごく助かるよ、きっとあなたみたいな人が他にもいるはずだから。

面白いプロジェクトだね。もし知らなかったら、Arcan(https://arcan-fe.com/)をチェックしてみて。 (追記:最近著者がリンクを追加したのを見たよ:https://github.com/tattoy-org/tattoy/blob/main/website/conte...)コントラスト比管理に関するいくつかのポイント: - ここでのMynexの回答は非常に参考になるよ:https://stackoverflow.com/questions/596216/formula-to-determ... - コントラスト比の「制限/境界」には「極性」(プラスマイナスの感覚)がある。少なくとも「テキスト」に関しては、ほとんどのフォントでは前景ピクセルよりも背景ピクセルの方が圧倒的に多いんだ。だから、例えば、あなたの目は全黒の背景に対してテキストセルの暗い背景色での前景と背景のコントラストを低く耐えられるけど、全黒の背景に対して暗い前景色ではそうはいかない。これは、テキストセルの外側の背景ピクセルが行っている「共有識別作業」に関係してるんだ。だから、実際にはただ二つのものの「比率」は少し単純化しすぎてる。 - XTerm OSC 4はカラーパレットを調べる能力が非常に限られているかもしれない。少なくともstではデフォルトの前景、背景、カーソルの色しか見えないし、フル16色パレットは見えないんだ。これは主に@hnlmorgによる他のスレッドのポイントを強調するだけだね。 - 最近のsshまでは、Linuxのデフォルト設定はすべての「LC_*」環境変数を通過させていた。だから、シェルのrc/configを調整して、例えば$LC_THEMEに「light」や「dark」が含まれるようにすれば、もっと低い技術的解決策で全てを再極性化できるかもしれない。私はいつもこれをやってて、黒い背景のターミナルと白い背景のターミナルを使い分けてるよ。(90年代には白黒のディスプレイが流行ったけど、最近の「カラーハッカー」は暗い背景を好むみたい。理由については理論があるけど、ちょっと話がそれるね。)https://github.com/c-blake/lc の設定にはもっと具体的な例があって、あ、色付きlsも気に入るかもしれないよ。(それと、1980年代の「全てを$TERMに詰め込んで再解析する」って古臭くて私には醜いアイデアも知ってる。セキュリティの懸念が私たちをその方向に押し戻すかもしれないね。)

すごい、いろいろ教えてくれてありがとう。前景と背景のピクセルの比率がテキストの可読性に影響を与えるなんて考えたこともなかったよ。もちろん、考えてみればそれは完全に理にかなってるね。これがWCAG基準のどこかで考慮されたことがあるか知ってる?パレットのスクリーンショットとOSC 4の両方をサポートしようと思ってるんだけど、LC_*変数は前に見たことがあるけど、今のシェルにはないみたい。これらがパレットインデックスの真の色の値の別のソースになり得るってこと?

XTerm OSC 4はカラーパレットを調べる能力が非常に限られているかもしれない。少なくともstではデフォルトの前景、背景、カーソルの色しか見えないし、フル16色パレットは見えないんだ。これは主に@hnlmorgによる他のスレッドのポイントを強調するだけだね。 どのstのバージョン?私の場合、0.9.2ではseq 0 255のnに対して色立方体全体を印刷するよ;do printf '\033]4;%d;?\033\\' "$n"; done; read(驚くことに、微妙に壊れてるけどね:STを送ったけど、応答がBELで終わっちゃう...)

プロトコルを進化させるアイデアが特に好きだな。テキストファーストのUIが素晴らしいアイデアだからって、ANSIエスケープコードで完璧に達成したわけじゃないからね。

ターミナルの状態を完全に仮想化してるの?それともビジュアルレイヤーだけをオーバーレイしてる感じ?例えば、子プロセスが不正なエスケープシーケンスを書いたり、フレームの途中でサイズ変更したりしたら、状態の解決は誰が担当するの?タトイそれとも基盤のTTY?