1つのRustコアにプラットフォーム別のシェルを載せた理由
3つのOSに同じエディタを提供するなら、UIを一度だけ作る方法があります。私たちはその道を一度進んでから引き返し、1つのコアにプラットフォーム別の薄いシェル群を載せました。

同じエディタをLinuxとmacOS、Windowsで提供するには、UIを3回作らなければなりません。
最初は、そのコストを避けたいと思っていました。1つのクロスプラットフォームツールキットを使って、3つのOSに同じ画面を描きました。その決定によって最初のパフォーマンスゲートを通過し、韓国語入力の最初のマイルストーンも達成しました。
ところが、優先順位が変わりました。
パフォーマンスはデザインより重要で、デザインはコストより重要である。時間とコストは制約から除外する。
この基準で見直すと、答えも変わりました。
1つのUIを諦めました
クロスプラットフォームツールキットには明確な利点があります。一度作った機能を複数のOSで使えます。
その代わり、支払わなければならないコストもありました。メモリを40〜60MB多く使用し、起動は150〜200ms遅くなりました。文字表現はOS標準のテキストエンジンに及ばず、システム固有の視覚効果も十分には使えませんでした。
開発コストが重要だったときには、合理的な選択でした。しかし、コストを制約から外すと、もはや受け入れる理由はありませんでした。
そこで、文書を処理するコアはRustで作り、画面を担当するシェルはOSごとに別々に作ることにしました。
既存の技術が悪かったからではありません。優先順位が変われば、同じ選択肢からでも異なる答えが出ます。私たちは機能を3回作るコストを払い、パフォーマンスと文字品質、システムらしい体験を取り戻すことにしました。
ただし、すべてを捨てたわけではありません。
計測の規律はそのまま引き継ぎました。ポインターをウィンドウの外に置くこと、ウィンドウを名前で正確に見つけること、フレームを同期して数えること。韓国語入力の設計原則も一緒に移しました。OSにはカーソルがある行だけを見せ、変換中の文字には装飾を加えません。状態が食い違ったら推測せず、再び同期させます。
コードを捨てても、検証された原則は残ります。
シェルの役割を小さく定めました
プラットフォーム別のシェルが多くの仕事を担い始めると、3つの製品はたちまち異なるものになります。そこで、シェルがすることと、しないことを明確に定めました。
シェルはウィンドウを作り、文字を描きます。キーボードとポインターの入力をコアに渡し、韓国語入力を編集コマンドに変換します。OSの視覚効果も適用します。
一方で、Markdownは解釈しません。改行以外のレイアウトも決めず、ファイルを保存したり、ライセンスを判定したりもしません。
この原則は、文書に書いておくだけにはしませんでした。シェルにMarkdownの解釈コードが入ると、自動チェックによってビルドが停止します。
1つのシェルだけで構文を処理し始めると、OSごとに結果が少しずつ異なる可能性があります。このような問題は見つけるのも困難です。1つのシェルでだけ表の見え方が異なっていても、実際の原因は表を描くコードではないかもしれないからです。
コアだけが長く残るようにしました
コアは、どのUI技術にも依存しません。ウィンドウがなくても、ターミナルで単独テストできます。
文書編集とMarkdownの解釈、元に戻す操作、検索、アウトライン、ファイル保存、エクスポート、ライセンス検証を、すべてコアが担います。

ユーザーがキーを1つ押すと、シェルはその入力をコアに渡します。コアは文書を修正し、変更箇所の周辺だけを再び解釈します。画面に見えている内容だけを計算したあと、変化した結果をシェルに返します。シェルは影響を受けた行だけを描き直し、1フレームを完成させます。
この過程で文書全体を読み直すなら、それは単なるパフォーマンスの問題ではありません。最初に定めた予算に違反しているのです。
正確性もコアで一度だけ検証します。CommonMarkの公式例652件すべてに合格する必要があり、合格数が減るとビルドが失敗します。予期しない入力を繰り返し与えるファジングテストも行います。
保存したファイルが元のファイルとバイト単位で同一かどうかも確認します。ラウンドトリップ率が1.0を下回るなら、遅いのではなく、ファイルを失っているのです。
シェルが変わっても、コアはそのまま残ります。LinuxとWindowsではコアを直接接続し、macOSではSwiftの接続コードを使います。macOSのシェルはAppKitとTextKit 2で、WindowsのシェルはDirectWriteで作っています。
文書は同じに、操作感はそれぞれのOSらしくすることが目標です。
文書は同じで、使用感は異なります
境界を定めると、何を統一すべきかも明確になりました。
統一すべきものは文書です。どのOSで保存しても、ファイルの内容はバイト単位で同一でなければなりません。表の配置と行末、最後の改行も変わってはいけません。
Markdownの正確性は、コアですでに検証しています。新しいシェルを作るたびに証明し直す必要はありません。新しいプラットフォームで確認すべきものは、使用感とパフォーマンスです。
反対に、手に触れる体験は統一しません。
文字は各OSのテキストエンジンで描きます。韓国語入力システムも、OSの方式を直接使います。半透明効果もmacOSとWindowsではシステム機能を使い、同じ機能がないLinuxでは必要な部分だけを直接描きます。
ウィンドウボタンの位置、メニューの形、ショートカットキーの修飾キーも無理に合わせません。異なるOSで同じピクセルを見せることが目標なのではありません。それぞれのOSで自然に感じられることのほうが重要です。
リリース条件もOSごとに定めました。パフォーマンス基準を通過し、標準の韓国語入力システムで実際のテストを終えなければ、リリースできません。
ベンチマーク表にそのプラットフォームの行が追加されるのも、実際にビルドができてからです。計測していない行を先に書けば、その表の残りの行まで信頼しにくくなるからです。
この選択には明確な代償があります
同じ機能を3回作らなければなりません。韓国語入力も3回実装し、ビルド環境も3組管理しなければなりません。
WindowsとmacOSは、現在使用しているマシンではビルドもデバッグもできません。別途ハードウェアと自動化環境が必要です。そのため、この2つのプラットフォームには日付を記載していません。
この決定を再検討する条件も残しました。コストを制約から除外したことが、決定の前提です。必要なハードウェアを確保できなければ、該当するプラットフォームのスケジュールだけを遅らせます。Linuxのリリースはそのまま進めます。
決定には理由だけでなく、考え直すための条件も必要です。そうすれば状況が変わったとき、議論を最初から繰り返さずに済みます。
長く残るべきものはコアです。シェルはいつでも捨てられなければなりません。
捨てられるものだけをプラットフォームに委ねました。