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

端末は256色のパレットを生成するべきです

概要

  • 256色パレット は、 base16テーマ から自動生成すべき提案。
  • base16テーマ は手軽だが、色数が少なく表現力に乏しい問題。
  • truecolor は柔軟だが、設定や互換性に課題。
  • 256色パレット の現状は、デフォルト配色がテーマと合わず視認性も低い。
  • base16テーマ から256色パレットを自動生成することで、設定の簡素化と表現力向上が可能。

ターミナルの256色パレットとbase16テーマの関係

  • base16テーマ は16色のみ定義し、ターミナルや多くのプログラムで統一的な配色管理が可能。
  • 16色では表現力が足りず、複雑なプログラムやカラフルな表示には不向き。
  • truecolor は約1600万色利用可能だが、各プログラムごとにテーマ設定が必要。
    • 設定ファイルが複数必要
    • ライト/ダーク切替には明示的な対応が必須
    • エスケープシーケンスが長く、パースも遅い
    • 対応するターミナルが少ない
  • 256色パレット はbase16より多彩で、truecolorほど複雑でない中間的な選択肢。
    • デフォルト配色がbase16テーマと合わず、視認性やコントラストも不統一
    • 240色を手動で定義するのは現実的でない

256色パレットの構造

  • 最初の16色 :base16テーマの色(黒・赤・緑・黄・青・マゼンタ・シアン・白+明色バリエーション)
  • 次の216色 :6×6×6のカラ―キューブ(各RGB成分が0~5段階)
    • インデックス計算:16 + (36 × R) + (6 × G) + B
  • 最後の24色 :グレースケールランプ(黒~白の間を等間隔で分割、純粋な黒・白は除外)
    • インデックス計算:232 + S(S=0~23)

256色パレットの課題

  • テーマの不一致 :デフォルト配色がユーザーのbase16テーマと合わず、違和感や見づらさを生む
  • 誤った補間 :色キューブの補間が明るすぎ、暗い背景での視認性が悪化
  • コントラストの不統一 :彩度が高すぎて、色ごとに明るさが大きく異なる

base16テーマから256色パレットを自動生成する利点

  • 8つの基本色 をカラ―キューブの8頂点に割り当てる
    • 背景色・前景色はbase16の黒・白の代わりに指定
  • 三線形補間 で216色キューブを生成
  • グレースケールランプ は背景~前景色で線形補間
  • LAB色空間 で補間することで、色相ごとに見た目の明るさを均一化

実装例(Python)

  • lerp_lab関数 :LAB色空間での線形補間
  • generate_256_palette関数 :base16配列と背景・前景色からパレット生成
    • 8色→LAB変換
    • 6×6×6キューブ→三線形補間
    • 24色グレースケール→線形補間
  • 出力 :256色のRGB値リスト

base16テーマから256色パレットを自動生成するメリット

  • 設定ファイル1つで多彩な配色 を実現
  • ライト/ダーク切替 もテーマ変更だけでOK
  • 幅広いターミナル互換性 を維持
  • プログラム作者は 256色パレット を安心して利用可能
  • truecolor より設定・互換性の負担が少ない

結論

  • デフォルト256色パレット は視認性やテーマ整合性に課題
  • base16テーマから自動生成 することで、設定の一元化と表現力拡大を両立
  • ターミナル側で自動生成 を標準化すれば、256色パレットの利用価値が大幅に向上

Hackerたちの意見

そうだね、指摘されると確かに納得できるし、すべてのターミナルはこの機能を追加すべきだと思う。これを24ビットカラーにも一般化できると思うよ。16色じゃユニークなトーンマップを特定するには足りないけど、パラメータをちょっといじれば、なんとか動くハッキーなものが作れるんじゃないかな。ただ、これはオプションにすべきだと思う(ターミナルの設定で持つオプションとしても、エスケープシーケンスでオプトアウトできるように)。なぜなら、ユーザーによっては変換したくないカラースキームでプログラムを設定している場合があるから。例えば、ターミナルがSolarizedカラースキームを使っていて、テキストエディタもSolarizedカラースキームを使っていると、色の変換が二重に適用されて変なことになるかもしれない。

面白いね。16色パレットからLUTを作って、24ビットカラー空間を24ビット以下の何かにマッピングできるかも。10ビットHDRを24ビットsRGBにマッピングする感じかな。アプリが設定をオーバーライドする代わりに、環境変数でやれば、ユーザーが簡単にオーバーライドできるから、マッピングがプログラムの見た目や使いやすさを損なうことがないかも。

256色パレットのいいところは、16-255の範囲の色が固定されているから、146が muted violet になるっていうのがかなり信頼できるってこと。これはカラースキームの開発者にとってすごく便利で、幅広いターミナルエミュレーターで一貫した体験を提供できるからね。もし256色パレットが、ちょっと変わった16色パレットから生成されると、146が本当に期待通りの146になる保証はなくなる。16-255を0-15と同じような危険地帯にするのは、ちょっと間違ってると思う。

実際にこの変更が ghostty でどうなるか見るのが楽しみだね!君の心配は、ほとんど無駄になると思うけど、例外もあるかも。影響を受けそうなターミナルアプリは何だと思う?テストケースは?ちゃんと読んでないけど、頭の中で考えてたのは、単に他の色を任意のパレットに置き換えるってわけじゃなくて、ユーザーの色を基にしたパレットのより良いバージョンを使うってこと。マゼンタは、ユーザーが選んだ青と赤から派生する感じ。デザインやクリエイティブとユーザーの間には常に緊張があるよね。アプリやデザイナーは自分たちのブランドアイデンティティを持ちたいし、思い通りに作りたいから、ユーザーの好みや希望を犠牲にすることもある。個人的には、それがすごく嫌だった。ユーザーがコントロールできるなら、ちょっとした変わった感じやファンキーな要素を許容したいと思う。でも、リスクを避ける気持ちもわかるし、物事がうまくいかないことを恐れて、厳しく承認されたシステム以外を禁止する強いルールを作りたくなるのも理解できる。だけど、そういう世界はクソだと思う。

iTerm2みたいなターミナルは、しばらく前から最小コントラストがあって、(前景)色に悪影響を与えることがあるんだよね。

16色が限られてるのはわかるけど、CLI/TUIの開発者がその範囲外の色を使って独自のテーマを作るのが一番のストレスなんだ。視覚障害のある人たちにとって読みづらいカラースキームを生成する可能性が高いから。目の快適さのために白や色付きの背景を好む人、非黒の背景の方が読みやすいと感じるディスレクシアの人、そしてプロジェクトや作業環境ごとに異なるカラースキームを好む人たちもいる。開発者はこのコントロールの喪失に対して、複数のカラースキームを作ってユーザーにアプリを設定させることで応じるんだよね。だから、ユーザーはターミナルのデフォルトを設定してから、ターミナルのデフォルトを無視するすべてのアプリを設定しなきゃいけなくなる(!!!)っていう。人々はターミナルを使うのは、見た目がいいからじゃなくて、テキストインターフェースの方が効率的だと感じるから。もし綺麗なものを作りたいなら、ウェブフロントエンドを作ればいい。でも、お願いだから、君の好きな色を押し付けるために私のターミナルを壊さないでほしい。

パレットのエントリーを再定義できるエスケープコードがあるよ。通常は16-255の範囲を含んでる。

ごめん、でもアプリ開発者のこの考え方、めっちゃイライラする。個人的には、IDEやターミナルでもどこでもライトテーマが好きなんだ。0-15のカラースキームを自分で選べば、好みのカラーパレットが得られると思ってたけど、なぜか君たち開発者が「自分たちの方が色の好みを知ってる」って思ってるせいで、全然足りないんだよね。TUIアプリごとに色の設定を別々にしなきゃいけないし、なんでみんなそんなことするのか理解できない。なんでわざわざユニバーサルなカスタマイズシステムを壊して、ユーザーにアプリ特有のものを使わせるの?正直、16-255色を使ってるアプリに出くわすたびに、誰かに自分のパーソナルスペースを侵害された気分になるし、合わない色で自分の選んだカラーパレットに入り込まれた感じがする。

一貫した体験を提供する そんなことしないでほしい。ここはウェブじゃないんだから。ターミナルでの色の使い方は、スタイル的なものじゃなくて、主に意味的であるべきだよ。私が知ってる人たちのグループを代表して言うけど、私たちは「一貫した体験」を求めてないし、色パレットを無理に操作しようとするTUIが大嫌い。色は控えめに、意図を持って使ってほしい。人それぞれ設定が違うことを尊重してほしいな。

146が muted violet になるという高い信頼性があるけど、その情報で何かできることある?この情報は、背景の色がわからないと役に立たないよね。テキストや他のすべての色も知っておくべきだし。もし背景が muted violet だったらどうするの?背景が白で前景が muted violet だったら?私のターミナルで「muted violet」を使ってほしくないんだけど、君たちには私のターミナルにどんな色があるのか全然わからないでしょ。

幅広い端末エミュレーターで一貫した体験を提供する。 「一貫した体験」を提供することを目指すのではなく、まずは一貫した機能を提供することを優先すべきだよ。 ユーザーが自分の体験をコントロールするのを妨げないようにね。

面白いアイデアだと思うけど、オプションとして設定できるようにして、デフォルトはオフにすべきだね。 ユーザーが適切な16色のパレットを設定すれば、古いユーティリティもすぐに見栄え良くなるかも。 そのアイデアには惹かれるな。

確かにややこしい状況だね。そこで、tinted themingを見つけたんだ:https://github.com/tinted-theming/base24/ これは結構いいつなぎの手段になってる。色のスキームを切り替えるためにtinted shellを使ってるよ。

これ、ametamericと一緒に試してみるべきかも。プロタノマリーがあるから使ってるんだよね。[0] https://ctx.graphics/terminal/ametameric/

まさにそのことを考えてた!でも、基本の16色でも問題があるんだよね:黒、赤、緑、黄、青、マゼンタ、シアン、白、明るい黒、明るい赤、明るい緑、明るい黄、明るい青、明るいマゼンタ、明るいシアン、明るい白。多くのテーマはblackを「黒」と、whiteを「白」と解釈するけど、ダークテーマとライトテーマを切り替えたときにどうなるの?blackwhitebright blackbright whiteはそれぞれ何を意味するの?私はそれを次のように解釈してる:現在のターミナルの背景に対してほぼ見えないかなりコントラストがある見えるけどコントラストがない最もコントラストが強い。色の名前がそれを反映してくれたらいいのに、blackwhiteじゃなくて、通常はコントラストを気にするんだから、正確な色よりも。

本来の使い方は、ターミナルの色には触れずにプログラムの色を設定することなんだ。だから、ダークテーマのために黒を反転させるんじゃなくて、プログラムが黒の代わりに白を使う感じ。ちなみに、ターミナルの前景と背景の色は、標準の16色とは独立してるから、ややこしいんだよね。

最新のiTerm2のコミットにこれが実装されたみたいだね。https://github.com/gnachman/iTerm2/commit/39bafa8d6651865951...

cargo/rustcにこれめっちゃ興味ある。基本的な意味のある色を使った後に、もう一色か二色必要になることがあるんだけど、残ってるのはマゼンタ(変な選択)、黒と白(テーマを確認しないと安全じゃない)だけなんだよね。

直接カラー モード(24ビット、「真の色」)を使えば、パレットは必要ないよ。

「真の色」をサポートしている端末は少ない。 私の知っている限り、今はすべてのOSの最新の端末エミュレーターがサポートしてるよ。

彼らは真の色について明確な意見を持っていたよね、今話してる記事の中で。

ユーザーがvimみたいなアプリに自分でカラースキームを追加するのはいいね。 だからこそ、開発者はデフォルトでアプリがユーザーの環境に応じて反応するようにしておくべきだよ。 複雑なビジュアルの選択肢を組み込むのはやめて、まずは使いやすさを重視してほしい。 工場出荷時からシンプルに保って、カスタマイズの邪魔をしないで。 ユーザーの環境が、ユーザーに合わせて適応する役割を果たすべきだね。

この新しいパレットは新しい制御コードの後ろに置くべきだと思う。それでオプトインの問題が解決するはず。