Ghostty 開発ログ 004
こんにちは! Ghostty 👻 の公式開発ログ第4回へようこそ!
これまでの開発ログを見逃した方、またはGhosttyについてもっと知りたい方は、このサイトのGhosttyページをご覧ください。
コミュニティの最新情報
先週、公開Discordサーバーを共有し、GhosttyとZigについて講演も行いました。どちらかを見逃した方は、ぜひご覧ください。新しいベータ版への招待はDiscordコミュニティを通じて配布しています。また、Discordコミュニティは600人を超えました。すごい!
前回のGhostty開発ログ以降、クローズドベータの参加者は約30人から約100人へと増えました。プロジェクト初期は、新たなベータ版の各ウェーブに参加するのは数人だけでした。しかしGhosttyが安定してきたことで、今では1ウェーブあたり15〜20人ずつ、安心してクローズドベータを拡大できています。これはとても良い兆候だと受け取っています!
美しいGUI
ターミナル内部の深い世界や古風な技術に飛び込む前に、GUIの改善と目を楽しませるものについてお話ししましょう。深く技術的な内容をお求めの方へ。後半のセクションではかなり細部まで掘り下げます。
macOSとLinuxのネイティブGUIはいずれも大きく進化しました。Linuxでは、Ghosttyにヘッダーバーメニュー、幅広のタブ(設定可能)、Aboutウィンドウなどが加わりました。Gnome Terminalや他のGTKベースのターミナルと並べても、Ghosttyは自然に溶け込んでいます。

Linuxではさらに、Sway、Hyprland、その他のコンポジタを介してWaylandを使うベータテスターも複数います。いくつもの問題を修正し、Ghosttyは現在Waylandで問題なく動作します。
macOSでは、システム設定に従うだけでなく、Ghosttyを常にダークモードまたはライトモードに設定できるwindow-theme設定を追加しました。私は個人的にmacOSをライトモードで使っていますが、ターミナルは常にダークにしているので、ダークモードを強制できます。また、フォーカスされていない分割ペインを薄く表示するようにしました(設定可能です)。とても美しく見えます。

Ghosttyが掲げる目標の一つは、利用中のプラットフォーム専用に作られたかのように感じられるネイティブな体験を提供することです。GUIの改善を非常に重視しており、Ghosttyが動作するプラットフォームの慣習に沿った設計となるよう徹底しています。上記の改善は、こうした理想に向けた進捗を示しています。
Vimのバグを発見! そして、ほかの行儀の悪いプログラムたち。
Ghosttyは、そのほとんどの期間にわたり、自身をTERM=xterm-ghosttyとして名乗ってきました。xterm-という接頭辞があるのは、多くの行儀の悪いプログラムが、ターミナルがある機能群をサポートするかどうかを判断するためにTERMへの文字列一致を行うからです。これは誤りであり、とても行儀が悪いです。やらないでください! 正しい方法は、terminfoデータベースを照会することです。
Terminfoは、それ自体とても興味深い話題です(主に、あまりにも呪われているからですが)。いつかterminfoだけを扱うブログ記事を書きたいと思っています。この開発ログではterminfoの詳細には立ち入りません。この古びた怪物を少し覗いてみたいなら、ターミナルでinfocmpを実行してください。
この1か月、xterm-接頭辞を取り除き、単にTERM=ghosttyになることを目指してきました。その過程で、自分たちのterminfoデータベースの多くのバグと、アップストリームの問題を見つけました。見つけるたびに両方を修正しています。
直近では、Vimのバグによって行き詰まりました。Vim 9.0はKitty Keyboard Protocolをサポートしていますが、対応ターミナルのリストをハードコードしており、terminfoデータベースを適切に尊重していません。これはバグです。そして驚くべきことに、Ghosttyコミュニティのメンバーが修正のプルリクエストを出してくれました。この問題はNeovimには影響しません。
Vimは少しばかり重要なものですから1、そのバグが修正され、下流のディストリビューションが広く更新されるまで、残念ながらTERM=xterm-ghosttyに戻さざるを得ませんでした。それでも、ここまで進められたことを誇りに思いますし、まもなくxtermという足かせを外せると楽観しています。
ほかにもアップストリームのバグを見つけました。そしてGhosttyコミュニティが問題を報告するだけでなく、修正まで提供してくれていることを誇りに思います。Timは、特に深刻な問題を修正するため、人気のGoライブラリtcellにPRを出しました。これはlazygit、lazydockerなどの人気TUIアプリケーションで使われている重要なライブラリです。この修正がなければ、これらのプログラムはTERM=xterm-256colorを明示的に指定して実行しない限り、すべてごみを吐き出します。早く受け入れられることを願っています!
これらのバグや修正はいずれもGhostty固有のものではなく、未知のターミナルエミュレータに対するプログラムの堅牢性向上に役立つはずです。
この作業は主にTim Culverhouseが主導しました。彼がここで成し遂げたすべてに、心から感謝しています。
XTGETTCAP(#563)
terminfoの大きな問題の一つは、実行中のプログラムが調べなければならないローカルファイルに依存していることです。つまり、リモートホストにSSH接続した際、そのホストにあなたのターミナルのterminfoがなければ、プログラムはターミナルで何ができるかを判定できず、誤った、あるいは最適ではない動作をする可能性があります。
XTGETTCAPは、ローカルファイルを読むのではなく、VTエスケープシーケンスを通じてターミナルのterminfoデータベースを照会できるターミナル機能です。これにはいくつかの利点があります。プログラムはバイナリ形式の解析方法やファイルパスの検索方法を知る必要がなく、リモートで実行中であってもterminfoを照会できます。
XTGETTCAPは次のようなものです。
# Query for stylized underline support (key "Smulx")
ESC P + q 536D756C78 ESC \
# Response from the terminal (Smulx=\E[4:%p1%dm)
ESC P 1 + r 536D756C78=5C45343A25703125646D ESC \完全に分かりやすいでしょう? 実際のところ、そこまで悪くはありません。プログラムはESC P + q <key> ESC \というテキストを送ります。<key>は16進数エンコードされた文字列です。上の例では、「Smulx」を16進数エンコードしています。応答には、そのterminfoエントリのキーと値も16進数エンコードされて含まれます。
実装上とりわけクールなのは、Zigのcomptime機能を使い、可能なすべてのリクエストと応答をコンパイル時に生成していることです。これは実際のterminfoファイルを生成するものと同じソースファイルから生成されるため、terminfoとXTGETTCAPは常に完全に同期します。
XTGETTCAPの性能はまったく重要ではありませんが、コンパイル時に最適化されたルックアップテーブルなので、GhosttyのXTGETTCAP実装はばかみたいに高速です。アロケーションや文字列フォーマットなどは一切必要ありません。単純なルックアップを行い、安定した文字ポインタを見つけ、それを直接ptyに書き込みます。とてもクールです。
これを生成するZigのスニペットをご覧ください。Zig comptimeが大好きです。
可変フォント(#345)
多くのフォントは、「Bold」「Heavy」「Medium」「Italic」など、固定されたスタイル一式を提供しています。一方、可変フォントは、ウェイトやスラントなどのさまざまな軸を、一定の範囲内で連続値として設定できる単一のフォントフェイスを提供します。Ghosttyは現在、可変フォントとバリエーション軸の設定をサポートしています。
まず、可変フォントがどのようなものかを見てみましょう。Inconsolataには可変フォント版があり、下の動画では文字幅とウェイトを細かく制御しています。
以下は、フォントのバリエーション軸を何も設定していない、Inconsolata使用時のデフォルトのGhosttyです。

こちらはウェイトを少し変更した設定です。差はわずかですが、分かると思います。まず設定、続いてスクリーンショットです。
font-family = Inconsolata
font-variation-bold = wght=500

上でなぜweightではなくwghtなのでしょうか? バリエーションのキーはフォントによって決まり、フォントバリエーションは4文字でなければなりません。これらは標準化されていないため、weightをwghtへ安全に変換することはできません。Ghosttyの設定ではバリエーションキーをそのまま使います。ユーザーは有効なキーを確認するために、任意のフォント検査プログラム(FontDropなど)を使えます。
ターミナルエミュレータで可変フォントをサポートする例は比較的少ないので、これをサポートできていることを誇りに思います(しかもクロスプラットフォームです!)。こうした機能により、ターミナルを思いどおりに細かく調整し、しっくりくるものにできます。
終わりに
今回のベータテスターの皆さんにも、改めて感謝します。毎回、とある専門分野に深い知識を持つ素晴らしい方々や、新しく独自の方法でターミナルを使い、問題を見つけてくれる方々が参加してくれます。
最新情報を追いたい方は、TwitterまたはMastodonをフォローしてください(リンクはフッターにあります)。このブログにはRSSフィードもあります。
ブー。👻
脚注
Bram Moolenaarさんのご冥福をお祈りします。私たちに与えてくれたすべてに感謝します。 ↩
記事をランダムに読む