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

自分専用のテキストエディタを作成し、日常的に使用する

概要

  • プログラマーにとってテキストエディタは不可欠なツールであり、理想的なものを求めて多くのエディタを試行錯誤
  • Howlというエディタの限界に直面し、自作エディタの開発を決意
  • 開発過程で機能の取捨選択やパフォーマンス改善、使い勝手の追求を重視
  • ファイルブラウザや正規表現エンジンなど、特徴的な実装ポイントを詳細に解説
  • 実用性と自分仕様を両立させるための工夫と反省点を共有

プログラマーのテキストエディタ遍歴と自作への道

  • テキストエディタ はプログラマーにとって「城」そのもの
  • 理想的なエディタとは、現実世界のあらゆるデータを 柔軟に扱える こと
  • 長年愛用してきた Howl は軽量で効率的だが、いくつかの致命的な欠点
    • 開発停止状態が続き、 自分でフォークして保守 していたが、MoonScriptという言語の習得意欲が湧かず大規模な修正が困難
    • プロジェクト全体のファイル検索が遅く、 フロー状態を妨げる
    • GUIエディタのため、SSH経由での利用や 統合ターミナル機能が不十分
  • LSP の利用習慣がなく、grep検索に強く依存
  • ネットワーク越しの作業が増え、 SFTPやGUIでは限界 を感じる
  • 代替エディタを多数試す(Helix、VS Code、Sublime Text、Vim、Zed、Neovim、Emacs、Geany、Micro、Lite XL、Lapce、GNOME Builder、Kakoune)
    • 各エディタに長所はあるが、 求める「指先感覚」 が得られず
    • Helixを最長で使うも、 決定的な魅力に欠ける と感じて自作を決意

自作エディタ開発のはじめ方

  • スコープを 徹底的に絞る ことから開始
    • 自分以外のための機能は排除、 全設定はハードコーディング
    • パフォーマンスは後回し、 バッファは文字列管理
    • Unicodeグラフェム対応は最小限、 主要言語のみサポート
  • 最初は進捗が遅く、 TUIフレームワークの自作 など過剰設計気味
    • 後にシンプルで細粒度なアプローチへ移行

実用投入と改善サイクル

  • nanoの代替 として徹底的に自作エディタを利用
  • 不足機能やバグ、違和感をREADME.mdに 全て記録
  • イライラした箇所は 即時修正 を徹底
  • この運用で開発時間が大幅増加、 10,000行以上のコード を半年で実装

カーソル操作の難しさ

  • カーソル操作 は直感的だが、実装は非常に複雑
  • 高度な入力操作は 基本操作の組み合わせ で実装推奨
    • 例:単語単位のバックスペースは、 単語移動+範囲選択+削除 の組み合わせ
  • Undo/Redoのグルーピングにも注意
  • モーダルエディタは 基本操作を直接ユーザーに公開 し、連携しやすい設計

ファイルブラウザのこだわり

  • Howlの ファイルブラウザ体験 が他エディタより圧倒的に優れている点に着目
    • インクリメンタルな ファジーフィルタ が非常に快適
    • ファイル新規作成やディレクトリ移動も 直感的に操作可能
    • プレビュー機能も充実
  • 他エディタは多くが マウス操作や標準ダイアログ依存 でストレス
  • 自作実装では、 シンプルな検索アルゴリズム (前方一致・部分一致・最終更新日時)を採用
    • ケース一致で順位調整、 実用性重視

正規表現エンジンの自作

  • 正規表現 は全体検索・シンタックスハイライト・バッファ内検索に活用
  • 既存ライブラリでは 文脈依存やネスト対応が不十分 なため自作
  • 独自のパーサとASTを構築し、 パフォーマンス最適化 を重ねる
    • パターンの合成、共通プレフィックスの抽出、スレッドコードVM化、CPS変換、バイト単位処理
  • ベンチマーク結果、 大規模ファイルのハイライトも10ms以下 で完了

シンタックスハイライトの最適化

  • 全再描画方式 から、 オンデマンドチャンクハイライト+キャッシュ 方式へ移行
  • 編集が発生した箇所のみ再ハイライト、 複数ペインにも柔軟対応
  • 実用上、 大規模ファイルでも十分高速

プロジェクト検索の実装

  • .git/ディレクトリ検出 によるプロジェクトルート特定
  • ルート以下を 再帰的に走査し、正規表現でマッチ
  • 実装詳細は省略されているが、 シンプルかつ効率的な検索 を重視

このように、 自作エディタ開発 は理想の操作感・機能・パフォーマンスを追求する過程で多くの学びと工夫が生まれる体験。既製品の限界を感じた時、自分の「城」を築く価値を実感できる。

Hackerたちの意見

90年代にエディターに手紙を書いたことを思い出すなぁ。COBOLやアセンブリファイルに「ms edit」を使いたくなかったから。シンタックスハイライト、速いバッファリング、さらにはスクリーンセーバーまであったんだよね。コンパイラも直接呼び出せたし。ペンティウム120で動いてたけど、今のVSCodeよりも何千倍も速く感じた。でも、VSCodeは複数のファイルを同時に編集できるんだよね…

古いノートパソコンでVSCodeを立ち上げたら、テキストエディターが全然動かなくなって、心の一部が死んだ気がした。自分はvimの時代から来たけど、今のツールでそれが正解だって人に言うのは難しいな。

でも、VSCodeは複数のファイルを同時に編集できる。ボーランドのターボパスカルやターボCも同時に複数のファイルを開けたよね。

そういえば、VB6で動くエディターを書いたことがある。検索と置換がうまく動いたときはめっちゃ嬉しかった。2002年のマーケティングページのコピーもまだ持ってるよ。無制限のカスタマイズ可能なテンプレートファイル、カスタマイズ可能なシンタックスハイライト、非常にカスタマイズ可能なユーザーインターフェース、色分け印刷(オプション)、カラム選択機能、正規表現による検索/置換、ブロックインデント/アウトデント、通常のテキストをASCII、16進数、バイナリに変換、文字列をn回繰り返す、ウィンドウズエクスプローラー風のファイルビュー(ドッキングウィンドウ)、無制限のファイル履歴、お気に入りのグループとファイル、各オープンドキュメント用の無制限のプライベートクリップボード、このエディターで開くファイルタイプの関連付け、ドキュメントの表示を最大4分割、コード補完(つまりIntelliSense)、Windows XPテーマサポート。あの頃は大文字のHTMLタグを使ってたよね。

ジョシュ・バレットは、スーパーマリオ64のGBAポートの天才だよ。彼のエディターを使うのは全然嬉しい!

彼のSM64の動画、めっちゃ好き!興味ある人のために最新のリンク貼っとくね: https://www.youtube.com/watch?v=nS5rj80L-pk

これ大好き!「難しい部分を統計の箱に押しやる衝動を抑えよう」という一文が特に心に響いた!

エディターはこちらだよ: https://git.jsbarretto.com/zesterer/zte

このスレッドの人たちで、テキスト編集ライブラリのおすすめがあったりする?自分のやり方でテキストエディターを作りたいんだけど、GUIじゃないとダメなんだ。理由を話すのは面倒だから省略するけど、その要件があるせいで、フォントレンダラー(少なくとも1つ)やグラフィックスコンテキストなど、いろいろ持っていかなきゃいけない。これらを全部やりながらテキスト編集ライブラリを書くのは、夜や週末の時間じゃちょっと無理がある。テキストエディターだけを始めると、ターミナルコンソールでしか動かないから、自分のプロジェクトには使えないし、GUIだけを始めると、実際には動かないから使えない。だから、プロジェクトの中心にあるテキスト編集ライブラリをカスタムコードに置き換えるとしても、何か始めるためのものがないと、正直言ってスタートすらできない。ここで解決策を見つけるのがこんなに難しいとは思わなかった。見つかるものは、自己完結型のテキストエディターか、フルオンの「ミッションステートメント」GUI(「私たちのエディターの機能を使えば開発が楽になる」みたいな)ばかり。入力を与えて、テキストコンテンツの状態更新を返してくれるAPIを見つけるのが本当に大変だった。CRDTとかなんでも。みんな、単におもちゃのテキストエディターを書くか、フルブローのショーケース製品を書くかのどちらかだと思ってるのかな。そうなると、「ウィンドウズのメモ帳アプリを再構築したいけど、大量の行を扱っても遅くならない」っていう開発者は、こういうよく解決された問題のライブラリを使うんじゃなくて、実際に高度なテキスト編集の行管理を実装しなきゃいけなくなるんだよね。

いくつかの軽量GUIテキストエディタはScintillaをベースにしてるんだよね(https://scintilla.org/)。これ、GTKやWindows、MacのGUIアプリに組み込めるクロスプラットフォームの編集コンポーネントを提供してる。編集とプレゼンテーション両方を考えると、ちょっと機能が多すぎるかもね。

テキストエディタを作ってるときに驚いたのは、現代のターミナルエミュレーターがANSI拡張を考慮するとどれだけ優れているかってこと。ファーストクラスのクリップボードアクセス、マウスイベント、精密なテキストスタイリング、フォーカストラッキング、システム通知、キーの押下/解放イベントなど、現代のターミナルエミュレーターなら全部可能なんだ。これだけあれば、かなり優れたエルゴノミクスなエディタUIを作るのに他に何もいらないよ。trolleyみたいなツールを使えば、アプリ全体をghosttyで動かすシムに包み込んで、ネイティブUIアプリとして見せることもできるよ: https://github.com/weedonandscott/trolley

プラットフォームの詳細がわからないとおすすめするのは難しいけど、GUIレンダリングが目的じゃないなら、raylibみたいなのがクロスプラットフォームのGUI API、特にテキストレンダリングにいい選択かもしれないよ。 https://www.raylib.com/

Hacker Newsで議論の続きを見る