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

LSPを介したCode-GUIの双方向編集

概要

  • リアルタイム双方向編集 を実現する小規模なPoCシステムの紹介
  • LSPサーバー とWebSocketsでエディタとGUI間のデータ同期
  • 任意のモダンなコードエディタ とGUIを連携可能
  • 既存の コードベースCAD ツールの課題整理
  • 今後の展望と期待

リアルタイム双方向編集のPoC構築

  • 自宅プロジェクト に役立つCAD環境の構築意欲
  • 快適な開発環境 (例: Emacs, Neovim)で作業したいというニーズ
  • Kevin Lynagh氏のcodeCAD における双方向編集のアイデアへの共感
  • ポイント :GUIでジオメトリを操作→ソースコード自動更新、コード編集→GUI自動反映
  • <textarea>による編集体験 への不満、理想は自分のエディタ利用
  • 実現課題
    • ソースコードの自動書き換え方式(ファイル監視、即時反映など)
    • エディタとUI間の同期・競合回避
    • LSPサーバーの必要性
    • コメントや整形の保持
    • 必要最低限の実装範囲の見極め

LSPサーバーによる双方向編集の可能性

  • LSP(Language Server Protocol) の活用経験
  • LSPサーバーとWebSockets によるエディタとWebアプリ間のリアルタイム通信
  • デモ概要
    • テキストエディタとGUIを並列表示
    • 双方向でデータが即時同期
    • 技術詳細やコードはGitHubで公開

既存コードベースCADツールの比較

  • 双方向編集自体 は新しくないが、 リアルタイムかつ好みのエディタ で実現する点が新規性
  • 既存ツールの課題整理:
    • Fusion 360 :パラメータの双方向編集は可能だが、完全なコードベースではなく、エディタも限定
    • OpenSCAD :外部エディタ利用可能だが、GUIへの反映は一方向のみ
    • Zoo :双方向編集は内蔵エディタ限定
    • Arcol :建築向けでプログラマー向けではない
  • 理想 :リアルタイム双方向編集+好みのエディタ+GUI連携の三位一体

今後の展望

  • 今回のデモは 実験的な試作 であり、今後の開発予定は未定
  • LSPサーバーの新たな活用方法 への期待
  • OpenSCAD+Neovim+OpenSCAD LSPサーバー の組み合わせが現時点で最良の体験
  • 本格的な実装には 競合解決・インクリメンタル編集・LSPサーバー内部実装 など多大な労力が必要
  • Kevin氏の今後のcodeCAD開発 への期待

LSP(Language Server Protocol)について

  • LSP はエディタやIDEで診断、コードアクション、定義ジャンプ、補完機能などを提供するプロトコル
  • Neovimなどの設定 でLSPサーバーが広く活用されている現状
  • Arcol では現在プログラマーを積極採用中、興味があれば james@arcol.io へ連絡推奨

Hackerたちの意見

いいアイデアだね!LSPをこんな風に使うなんて思いつかなかった!ソフトウェア開発者として、グラフィカルな作業をしているときに、描いているもの(木製のキャビネットや家具、部屋のレイアウト、設置計画など)をきれいにパラメータ化するのに苦労することが多くて、コーディングとGUIの切り替えにイライラするんだ。今まで使った中で一番良かったのは、PythonバインディングがあるFreeCADかな(小さなライブラリをいくつか作って、コンポーネントを構築してもらったりしてる)。でも、自分のエディタを使えるとはいえ、体験はあまりスムーズじゃないんだよね。だから、ここにあるようなツールを想像し始めるんだけど、もちろん自分にぴったり合うように(コーディングとGUI作業のバランスを取る感じで)やってほしいな。

コードかGUIのどちらかを選ばなきゃいけないことにフラストレーションを感じている開発者がたくさんいると思う…どちらにも使い道があるけど、両方を組み合わせたシステムがあるはずだと思うんだ。

Pythonベースのbuild123dって、今のところ一番のCAD in codeソリューションじゃない?OpenSCADの問題は、ソリッドジオメトリをエクスポートできなくて、最終的なメッシュしか出せないことだよね。もっと広く言うと、これを使って遊んでいるときに、シンプルなデザインコンセプトさえもキャッチできるクロスCADファイルフォーマットがないことに本当にショックを受けたよ。「この穴はこのプレートの中心に合わせてある」とか「これは2mmのフィレットだ」とかね。STEP(ファイルフォーマット)は、最終的なジオメトリしかキャッチしないし。CADの人たちは、Fusion 360からFreeCADに移る必要があるとき、また部品を再設計するんだろうね。そんな風に生きていけるの?

彼らはあまりプログラムを変えないと思うし、プロジェクトの途中で変えることはめったにないんじゃないかな。

STEPは、君が説明する内容をキャッチできるんだ。ただ、CADベンダーの「ユーザーグループ」がそれを各CADシステムに実装してもらうように頼む必要がある。次のSTEP AP242の版に向けて、ユーザーグループともっと密に連携してこの分野を改善するための資金を申請したよ。

CADカーネルが最終的なBREP形状をプロセスツリーを通じて生成する仕組みを知らないと説明するのは難しいけど、例えば「これは2mmのフィレットです」とか言うと、カーネルに深く組み込まれた「フィレットソルバー」が必要なんだ。Fusion360からCATIAにそのまま持っていけるようなものじゃないから、全然違うカーネルでモデルを「解決」する方法も違うし(フィレットだけじゃなくて、すべてにおいて)。だから、最終的なBREPマニホールドソリッドを含むSTEPが標準的なインターチェンジになっているんだよ。これはポータブルな解決済み出力の最終的な表現で、他のものは... 難しいんだ。

相互運用性の問題は、CADカーネルが独自のB-rep表現や制約ソルバーを使っていることから生じていて、STEPのAP242標準は製品製造情報(PMI)やセマンティックアノテーションを含めることでこれに対処しようとしているけど、採用はまだバラバラなんだよね。

これは1990年代のBorland Delphiの機能に近いね。Pascal言語と彼らのGUIツールキットのデザインは、本当に良いインピーダンスマッチだったから、GUIデザインとそのテキストバージョンの編集を自由に切り替えられたんだ。C++みたいな言語だと、触れられないボイラープレートの海だったから、Pascalから離れられなかったんだよね。WxPythonやそのビルダーにも似たような脆さがあったし。LLMがあまり適していない言語とGUIの組み合わせにマッチできるのを見て嬉しいよ。みんな、そのくらいの生産性を得る価値があるよね。

Delphiのフォームファイルはパスカルじゃなかったよ。GUIの同期は、コンポーネントやイベントハンドラーを追加する時にクラス定義を編集するだけだった記憶がある。

Borland C++ BuilderもDelphiと同じことをやってたよ。DelphiのVCLクラスライブラリを使って、すごくうまく動いてた。

LSPは使ってないけど(いいアイデアだよね!)、私のこのプロジェクトはGUIとシェルパイプラインの双方向マッピングをやってるよ。スクリーンショットとGIFで説明してる! https://github.com/williamcotton/guish

いいね!こういうのめっちゃ楽しい!私もライブコーディングに関連した実験をいくつかやったことがあるよ。実際に動いてるプログラムがリアルタイムで更新される小さなプロジェクトを作ったんだ(保存なしで)。LSPを使って、すべての値がリアルタイムで更新されるのを見られるよ。 https://github.com/jasonjmcghee/livelove それに、テキストをインラインで置き換えるような数値スライダーやカラーピッカーのインタラクティブ性も追加したよ(VS Codeの拡張を通してだけどね): https://gist.github.com/jasonjmcghee/17a404bbf15918fda29cf69... それから、エディタを操作して位置を選ぶために「ドラッグ&ドロップ」できるようにした実験もあるよ。キーを押すと計算された位置を静的なものに置き換える感じで。 https://clj.social/@jason/113550406525463981 ここでできることは本当にたくさんあるよ。

あなたのプロジェクトが大好き!LSPを使って何か作ってるんだけど、あなたのコードは可能性のいい例だよ。

それはクールだね!誰かが以前にこんなことをやったに違いないと思ってたよ。

AutoCADってLISPで動いてるんじゃないの?

ゲームプログラミングに挑戦したいと思ってて、Love2Dを見てたんだ。Luaについては、NeoVimの設定でちょっと触ったくらいであんまり詳しくないけど、これなら始めやすそう!数学や物理のプログラミングは苦手なんだけど、昔Flashで粒子デモみたいなものを作ってたから、すぐに変更して結果を確認できるのはすごく助かる。シェアしてくれてありがとう!

バイディ同期のデモは https://new.rt.ht をチェックしてみて!PDFのやつが特に面白いよ!このプレイグラウンドはバイディ同期のために作られてるんだ!

え、これ何?!めっちゃクールだね!

Slint [https://slint.dev]というネイティブGUIツールキットのために、ライブプレビューと編集ができるLSPサーバーも開発したんだ。オンラインで試せるよ、https://slintpad.com に行って、ツールバーのボタンをクリックして右パネルを有効にすると、UIからプロパティを編集できる。これ全部LSPを通じて行われていて、対応しているエディタならどれでも統合できるよ。

すごい!これってどうやって動くの?例えば、どのUI要素がどのテキスト要素に対応してるかどうやって知るの?レンダリング中に追跡してるの?UIの変更はどうやって伝播させるの?テキストを更新してから全体のUIを再レンダリングするの?

Darwiniumでは、vscodeのwebviewを使って結構これをやってるよ。UIコンテナとLSPを含むホストの間でpostMessagesを使う似たようなプロセスなんだ。これで一番苦労したのは、言語サーバーからの診断(範囲ベースであることが多い)を、どうやってUIコンポーネントにマッピングするかだった。結構複雑なpubsubシステムを使って、UIコンポーネントをツリーの特定の部分に明示的にマッピングする必要があるんだ。いつかこれを共有できたらいいな。

LSPのアイデアが存在するのがちょっと心配だよ。数年前にCasey Muratoriが言ってたけど、ライブラリのやり方としてはかなり悪化してるって。HTTPを導入するくらいなら、DLL/SOへの関数呼び出しで済むのに。何のメリットがあるの?vimやemacs、$editorがネイティブプロトコルを話せばそれで終わりじゃん。そうすれば、GUIは実行中のエディタプロセスに直接組み込まれるし…ね?LSPをローカルマシンで動かすつもりだったから、セキュリティリスクは以前と変わらないと思うんだけど。

MCP、絶対気に入るよ。

これについては確かに疑問に思ってた。なんで言語理解の標準が特にサーバーでなきゃいけないの?良いアーキテクチャだから?vscodeは最初からクライアントサーバーアーキテクチャでスタートしたから、めちゃくちゃ恩恵を受けてるって聞いたことがある。ブラウザベースのエディタとして始まったからね。サーバー上で直接コードを編集したり、コンテナ内で作業するのが簡単なのは、クライアントサーバーだからなんだ。vscodeとLSPは両方ともMicrosoftの製品だし、Microsoftがクライアントサーバーの方向性を推進してるのかもね。

実際的なメリットはたくさんあるよ:1. 自然に非同期 2. 各サーバーとエディタ自体がそれぞれの言語とランタイムで簡単に書ける 3. サーバーはOOMエラーでクラッシュしたり、終了したりしてもエディタには影響しない 4. 多くの言語ではサーバーを書く方がC ABIを呼び出したりエクスポートしたりするより簡単 5. エディタはブラウザで動作し、リモートサーバーに接続できる 6. リモートの中央サーバーを持つこともできる。これらは実際に行われていることだよ。

こちらは、トークのライブプログラミング部分でのリーダブルなウィジェットの似たような例です:https://www.youtube.com/watch?v=c5LOYzZx-0c