D-Dev-Dock
D言語製のD言語エディタ
ハッカソンキーワード
今回のキーワードは "D"
背景
キーワード D から D言語を使いたい!
けど"D言語"のようなわからない言語で環境を汚したくないな...
そうだ!それをプロダクトにしよう!
プロダクト
D言語で開発されたD言語ランタイムをバンドルした IDE
機能
- マルチタブエディタ — 複数ファイルをタブで管理し、切り替えながら編集できる
- ファイルタブの移動・削除 — タブの並び替えおよびタブ単位でのファイルクローズ
- コード実行(Run) — メニューからD言語コードをビルド・実行できる機能
- シンタックスハイライト — libdparseを利用したD言語のリアルタイム構文ハイライト
- ネイティブGUI — dlanguiによるWindowsネイティブデスクトップUI
開発過程
1. 背景
ハッカソンのテーマキーワードが「D」だった。それならD言語を使おうと決め、加えて「D言語の開発のために自分の環境を汚したくない」という思いが重なった。そこで、D言語のランタイムを内包したD言語専用のコードエディタを作ることにした。
2. 技術選定
せっかくならD言語100%で作りたいという方針のもと、以下を選定した。
- dub — D言語のパッケージマネージャー(npm的な)
- DlangUI — D言語で書かれたクロスプラットフォームGUIライブラリ
- libdparse — D言語で書かれたD言語パーサー
3. 設計
テーマの「D」にちなんでDDD(ドメイン駆動設計)で開発を開始。domain / application / infrastructure / presentation の4層構造で設計を進めた。
4. MVPの実装と問題の発覚
ファイルツリーとファイル編集機能を持たせた最低限の実装を進めたところ、複数の問題が重なった。
- dlanguiのシングルスレッド制約 — UIの更新はすべてメインスレッドで行う必要があり、DDDのユースケース層でロジックを分離しようとするとイベント処理の流れと噛み合わなかった
- D言語エコシステムの薄さ — 初めてのD言語開発にもかかわらず、日本語はもちろん英語の情報も少なく、dlanguiの挙動を調べるにもソースコードを直接読むほかない場面が多かった
- DDDそのものの重さ — 未経験の言語 × 情報の少ないGUIライブラリ × DDD という組み合わせは設計コストが大きすぎ、ハッカソンの時間軸に対して明らかに見合わなかった
5. DDDを断念 → Featureベースへ
DDDを潔く捨て、機能単位でファイルを切るFeatureベース構成に切り替えた。タブ管理・エディタ・ファイルI/Oといった機能ごとにモジュールをまとめるシンプルな構造にしたことで、dlanguiのイベントモデルと素直に向き合えるようになった。
切り替えてから当日中に動くものが完成。設計の複雑さを手放したことで、かえって開発のスピードと見通しが一気に上がった。
6. UIとシンタックスハイライトの実装
アーキテクチャの問題は解消したが、次はUI・デザイン面で別の壁にぶつかった。
dlanguiはメンテナンスが止まって久しいライブラリであり、ドキュメントはほぼ存在しない。ウィジェットの種類も現代的なGUIフレームワークと比べると限られており、「やりたいこと」と「できること」のギャップを埋める作業が実装の大半を占めた。APIの挙動を調べるには内部の .d ファイルを直接読むしかなく、AIに聞いても学習データが乏しいため的外れな回答が多かった。結局、AIにソースコードを読ませながら一緒に解析するという方法で実装を進めた。
ここで下地として機能したのが、過去の.NET(WPF / WindowsForms)開発の経験だった。GUIアプリのイベントモデル、レイアウトシステムの考え方、ウィジェットのライフサイクルといった概念はdlanguiでも本質的に共通しており、初見のライブラリであっても「どこを疑えばいいか」の勘が働いた。ウィジェットの挙動のおかしさに気づくのも早く、WPFで似た問題を踏んだ経験が「これはイベントの伝搬順の問題だ」「レイアウトパスのタイミングがずれている」といった仮説を立てる起点になった。
具体的に踏んだ問題を挙げると、ウィンドウの最大化・リサイズが意図通りに動かない、画面内パネルのリサイズが効かない、ウィジェットを重ねた際のクリック・ドラッグ操作判定が意図しない要素に吸われる、レイアウト計算の結果ウィジェットが想定外の位置・サイズで描画される、イベントが期待通りに発火しない——といった不具合が次々と出た。
対処は基本的にソースコードを読んで挙動を把握し、使い方を変えながら試すことだった。APIの呼び出し順を変える、プロパティの設定タイミングをずらす、レイアウト構造を組み直すといった試行錯誤を繰り返した。解決しきれないものはUIの配置そのものを変えて回避し、挙動が安定しない機能は一部断念して別の操作で同じ目的を達成できるよう代替手段に切り替えた。
シンタックスハイライトの実装でも独自の落とし穴が連続した。syntaxSupport のセットタイミングによってハイライトが無効になる問題、libdparseがキーワードの tok.text を省略する仕様、dlanguiの色フォーマットでアルファ値の定義が一般的な慣習と逆になっている問題(0xFF が不透明ではなく完全透明)など、いずれもドキュメントには記載がなくソースコードを読んで初めて判明したものばかりだった。これらのハマりポイントはQiitaにまとめた。
苦労した点・学び
最大の苦労は「情報がないこと」そのものだった。 公式ドキュメントが不完全、日本語情報は皆無、AIも頼りにならない——という状況で、ソースコードリーディングが唯一の手がかりになった。これはつらい経験だったが、同時に「ドキュメントがない技術を使いこなす力」として確かな自信になった。
設計の面では、DDDへの挑戦と断念が大きな学びになった。「設計の正しさ」よりも「今の制約と規模に合った設計を選ぶ判断」の方が重要だと体感した。ハッカソンという時間制約の中で潔く切り替えたことで、動くものを届けられた。
UIの実装を通じては、ライブラリの制約を理解したうえでその中でできる設計を探すというアプローチが身についた。思い通りにならない道具に対して、設計側で折り合いをつけながら目的を達成するという実践知は、今後どんな技術スタックでも活きると感じている。
また、過去に.NETでWPFやWindowsFormsを触っていた経験が、思わぬ形で生きた。GUIの概念自体は言語やフレームワークを超えて共通しており、「デスクトップアプリ開発の経験」が異なる技術スタックでも確実に転用できることを実感した。技術は変わっても、積み上げた経験は無駄にならない。
今後の展望
なし!もうD言語は触りたくない;;