Web開発
よし、自分でテキストエディタを作ろう
Fine, I'll build my own text editor (dbushell.com)
要約
開発者は、現代のソフトウェア、特にテキストエディタの品質低下に不満を感じ、独自のテキストエディタ開発に着手しました。当初はCanvas要素でレンダリングを試みましたが、アクセシビリティやインタラクティブ性の問題に直面しました。次にcontenteditable属性を持つdiv要素を試したところ、ネイティブな機能(テキスト選択、アンドゥ/リドゥ)を活用できましたが、パフォーマンスの問題が見つかりました。最終的に、より長文のテキストに優れたパフォーマンスを示すtextarea要素が有望であると結論づけ、構文ハイライトなどの機能追加の可能性を探っています。
全文翻訳
よし、自分でテキストエディタを作ろう! 2026年9月1日火曜日Synthesised Audioを再生する「もうSublime Textのようなものは作られていない」という言葉は多くの人に共感を呼びました。最近のソフトウェアはゴミです。それが私に考えさせました。私はゴミを作るのが得意です!なぜ自分でテキストエディタを作れないのでしょうか?VS CodeはMonaco Editorを基盤としていますが、それは<div>のスープ地獄です。私は長年、私のIntel Inside™ Macが遅すぎたため、VS Codeの波に乗り遅れていました。Apple Siliconを購入したときにその問題は解決しました。それが基準なら、私は間違いを犯す余地がたくさんあります。Canvas私の最初の実験は、すべてのレンダリングを<canvas>要素で行います。あなたにはわかりませんが、CPUは毎秒60〜120フレームでその画像をレンダリングするために多くの作業をしています。インタラクティブ性の欠如は、テキストエディタにとって明白な問題です。私は「最小限実行可能」な機能のリストを作成し、それらを実装しました。テキストカーソルを配置するためのポインタダウンテキストカーソルを移動するための矢印キー現在の行をハイライトするテキストを入力するためのタイプ入力ファンシーなカーソルアニメーション次のデモはインタラクティブです。クリックして入力してください。Vimバインディングについて私を叩く前に:黙ってください、私はもっと差し迫った問題を抱えています。Canvasは何も無料で提供してくれません。多くの望ましい機能の中で、私は以下を欠いています:テキスト選択アンドゥ/リドゥ履歴複数行ペーストオーバーフロースクロール最後のものは非常に重要です。人生はカスタムの弾性スクロールバーを実装するには短すぎます。私はネイティブブラウザのオーバーフローを隠し要素で使用することにしました。<div>はCanvasテキストに合わせてサイズ設定され、スクロール位置はCanvas上のレンダリングオフセットを計算するために使用されます。それがうまくいっていることに満足していますが、<canvas>は完全にアクセシブルではないため、落胆もしています。テキスト選択やその他の機能を追加し続けることはできますが、根本的なアクセシビリティの問題を解決しているわけではありません。もっと良いアイデアがありました。Content editableCanvasでテキストをレンダリングする代わりに、ネイティブにオーバーフローdivでレンダリングし、contenteditable属性で編集可能にすることができます。その属性には、コードに最適なplaintext-only値があります。すべてのコンテンツは単一のテキストノード内に保持されます。<div contenteditable="plaintext-only" autocapitalize="off" autocorrect="off" spellcheck="false" translate="no"> <!-- text goes here --> </div>コードをコピー入力遅延のスパイクを避けるために、spellcheckのような属性は無効にする必要があります。その修正を発見するのに何日かかったか推測したいですか?数日!contenteditableを使用すると、ネイティブのテキスト選択やアンドゥ履歴などが利用できます。ブラウザによって、多くのアクセシビリティ機能が無料で提供されます。Selection APIは、カスタムテキストカーソルをレンダリングし続けるために使用するメトリックを提供します。::selectionが利用可能なので、それをスタイル設定することもできます。ネイティブのキャレットカラーは非表示に設定しましたが、これはおそらくNGでしょう。contenteditableテクニックは有望ですが、特定の文字数を超えると奇妙なパフォーマンスの問題に気づきました。ChromiumブラウザはWebKitや現在のFirefoxよりもパフォーマンスが劣りますが、予測不可能です。Textareaplaintextの代わりにcontenteditableは、単純な<textarea>で実現可能でしょうか?短く言うと:はい。長文テキストの場合、<textarea>の方がはるかにパフォーマンスが高いことがわかりました。この最後のデモでは、構文ハイライトも追加しました。私の元の計画は、contenteditable要素でカスタム::highlightを使用することでした。<textarea>はCSSハイライトを使用できないため、3番目のレイヤーが必要でした。デモ目的で、MicroLighterを適用するために、表示されている行のためにいくつかの<div>スープを追加しました。編集:新しいOpaqueRange APIが<textarea>のカスタムハイライトを解除すると聞きました—素晴らしい!編集2:そしてEditContext APIは<canvas>入力を改善します。CSSハイライトが多すぎると、別のパフォーマンスのボトルネックになります。より堅牢なソリューションは、Tree-sitterを使用して構文ツリーを生成し、それをウォークして表示されている行のみのハイライトを生成することです。仮想スクロールを完全に回避したいと思っていましたが、逆スティッキーテクニックを使用して改善できるかもしれません。または、編集するファイルサイズがパフォーマンスの壁に当たらないため、contenteditableに戻ることができます。とにかく、うまくいっているように見えますね?テキストエディタの90%で、機能の1%のように見えます。ここから先は、フクロウの残りを描くのはかなり簡単です。描き続ける誘惑に駆られますが、タブインデントのような小さなことをすべて考えてしまいます。今はタブキーを乗っ取ってスペースを2つ挿入しています…上記の私のデモは最適化されておらず、完全にアクセシブルではありませんが、少なくとも負け犬の立場から始めていません。<canvas>でのレンダリングは悪夢になるでしょう。このプロジェクトは雨の日のためにしまっておきます。JavaScriptの文字列とテキスト範囲はUTF-16コードユニットで機能します。単純にバグを導入するのは簡単です。私のデモはそれらでいっぱいだと確信しています。コード例を残して、オタクを狙い撃ちします。🍋🟩.length; // 5 [...