VS Codeのエージェントモードを拡張するには、を試してください!

Markdown 言語サーバーの紹介

2022年8月16日 マット・ビアナー、@MattBierner

2016年に Visual Studio Code に参加した際、Markdown のサポートは私が最初に担当した機能でした。いやはや、本当に6年も経ったのでしょうか?しかし、それは素晴らしい組み合わせでした。私はMarkdownを十分に長く扱ってきたため、Twitter、Outlook、そしてカーソルが置かれるほとんどすべてのテキストボックスに、希望を込めてバッククォートやアスタリスクを入力していることにしばしば気づきます。長年にわたり VS Code の組み込み Markdown サポートを成長させ、Markdown 拡張機能がウェブビューやノートブックのようなコア機能を直接的、間接的に形成してきたのを見るのは、信じられないほどやりがいのあることでした。

だからこそ、私が過去半年間ひそかに取り組んできたプロジェクト、そして VS Code の Markdown ツールにおける次の一歩を代表するものと私が考えるプロジェクト、すなわち Markdown Language Server について共有できることに興奮しています。この言語サーバーにより、ドキュメントのアウトラインからスマートな折りたたみ、パス補完まで、VS Code の組み込み Markdown 言語ツールのほとんどが他のエディターやツールで利用できるようになります。私たちの目標は、プログラミング言語により頻繁に関連付けられる種類のインテリジェンスで、Markdown ツールの進化を推進することです。

Markdown Language Server の取り組みは、2つの新しい(そして似た名前の!)オープンソースライブラリに分かれています

これらのライブラリはまだ初期段階ですが、VS Code 1.70以降のバージョンで既に利用されています(そして願わくば、あなたはそれに気づきさえしなかったでしょう :-))。この切り替えによって、Markdown ツールを別のプロセスに移動して他の拡張機能をブロックしないようにするなど、いくつかの利点も見られました。

しかし、話が先に進みすぎる前に、あなたは疑問に思っているかもしれません: なぜ Markdown 言語サーバーが必要なのでしょうか?正直なところ、私自身がこれに気づくまでには6年かかりました。これはまた、Markdown を単に数個のアスタリスク、角括弧、シャープ記号が散りばめられたプレーンテキストと見なしていた状態から、TypeScript や Python のようなプログラミング言語向けに出荷しているのと同じ多くのツールの恩恵を受けられるマークアップ言語として理解するようになった、私の進化をたどるものでもあります。

Markdown ツールに本格的に取り組む

VS Code を発見する前、私は主にシンプルなテキストエディターでコーディングしていました。これは、シンボル名を覚えて、それらを使うたびに手入力しなければならないことを意味しました。変数の名前を変更したい場合は、テキストの検索/置換を行い、ユニットテストが名前の誤入力や破損といった避けられないケースを捉えてくれることを願っていました。それは遅く、信頼性の低い作業方法でしたが、もっと良い方法があることを知らなかったので、私は満足していました。私のワークフローがいかに原始的であったかを真に理解したのは、ようやくよりスマートなツールを手に入れてからのことでした。

最近、Markdown でも同じことに気づきました。長年、私はVS Codeの比較的シンプルなMarkdownエディターで満足していました。構文の強調表示と組み込みのMarkdownプレビューに満足していました。ドキュメントのアウトラインとクリック可能なエディターリンクは、ただのおまけでした。リンクを手書きすることに慣れていました。ヘッダー名を変更した場合、そのヘッダーへのすべてのリンクを更新するためにテキスト検索を行う必要があると受け入れていました。そして、Markdown を装飾されたプレーンテキストに過ぎないと考えていたため、より良い方法が可能であるとは想像すらできませんでした。

しかしある日、画像パスを100回目かというほど打ち間違えた後、ついに気づきました: これは楽しくない!なぜ私は人生を無駄にして、これらのリンクを手作業で入力し、検証しているのだろう?それこそツールの役割だ!私はただのツールが欲しいのではなく、WYSIWYGスタイルのUIマジックの裏にMarkdownソースを隠すのではなく、テキストとしてMarkdownを読み書きするのに役立つツールが欲しかったのです。それは、VS Code の精神、そしてプログラミング言語のサポートについて私たちが考える方法と非常に一致しています。なぜ、従来のプログラミング言語に提供しているのと同じ多くのインテリジェンスが Markdown にも適用されないのでしょうか?私はその翌日、リンク補完の作業を開始しました。

リンク補完とは、現在のファイル内のヘッダーやワークスペース内の他のファイルへのリンクを作成するのに役立つ提案機能です。他の Markdown ファイル内のヘッダーへのリンクを補完するサポートも追加しました。素晴らしい!それは小さな追加でしたが、私の生産性に大きな違いをもたらしました。すぐに、これなしでどうやって生きてきたのか想像できなくなりました。

Markdown 補完の成功に舞い上がり、次にどのような言語インテリジェンスを Markdown にもたらせるかを想像して、私はうっとりしました。ヘッダー上で自信を持ってF2キーを押し、安全に名前を変更する自分を想像しました。濁ったテキストの海の中から赤い波線が光り出し、無効なリンクを特定するのを助けてくれるのを夢見ました。すべてがとても明白に思えました!なぜ何年も前に思いつかなかったのだろう?私は Markdown を単なるプレーンテキストではなく、構造化されたテキストとして理解し始めており、より良い Markdown ツールへの可能性は無限に思えました。

Markdown 言語機能

すべての新機能の裏話や、それらがどのように実装されたかの詳細については、皆様を退屈させることはしません。一言で言えば、私は段階的なアプローチを取りました。これにより、VS Code の Markdown サポートに割ける限られた時間で、すべての作業が可能になりました。例えば、直接リネームサポートの構築に飛びつくのではなく、まずすべての参照を検索の堅牢なバージョンを稼働させました(シンボルをリネームするには、まずそれが参照されているすべての場所を知る必要があるためです)。段階的に作業を進め、各機能を積み重ねていくことで、新しい機能を実装しながら古い機能もテストするのに役立ちました。例えば、リンクのリネームを実装することで、リンク検出に関する多くのバグを発見できました。(このアプローチの唯一の欠点は、自分の「非常にエレガントな」塔が、いくつかの非常に複雑な正規表現の上に築かれていることに気づくことです)。

晩春に無効なファイル/画像リンクの報告に関する実験的サポートが展開されたとき、私は一歩下がって自分の作業を概観しました。Markdown 言語機能のセットには現在、以下が含まれています

  • ドキュメントのアウトライン
  • ワークスペースシンボル
  • ドキュメントリンク
  • スマートな折りたたみ
  • スマート選択
  • 補完
  • 名前の変更
  • すべての参照を検索
  • 定義へ移動
  • 壊れたリンクの診断
  • ファイルの移動/名前変更時のリンク更新

これらの新しいツールが Markdown での作業をより速く、より安全にするだろうと私は知っていました。しかし、プログラミング言語に共通するこれらの機能リストを見直すうちに、ある考えが私を悩ませ続けました。数ヶ月前にはばかげていると却下したものでしたが、今、改めて考えてみると、ついに Markdown 言語サーバーの時が来たのかもしれないと気づきました。

サーバー化されていますか?

2022年晩春の時点では、VS Code の Markdown ツールはすべて通常の拡張機能 API上で動作していました。これらのツールすべてを適切な言語サーバーに移行することを検討したかったのですが、その変更には実際のエンジニアリングコストがかかります。それが価値のあるものであることを確認する必要がありました。

私はこれについて1ヶ月以上も悩み続けました。既存のコードはまずまずの状態でしたが、未知の要素がたくさんありました。もし途中で、それが機能しないことに気づいたらどうしよう?私はこれまで真剣に言語サーバーに取り組んだことさえありませんでした。

これらすべてを議論する中で、私は Markdown 拡張機能のソースコードを、あたかも言語サーバーに移行されるかのようにリファクタリングすることで、忙しくしていました。VS Code の拡張機能 API への依存関係を分離しようとし、より多くのロジックをサービスインジェクションを使用するように切り替え、テストがファイルシステムに依存しないようにしました。そうすることで、たとえ言語サーバーへの移行に踏み切らなかったとしても、少なくともコードベースをクリーンアップすることはできました。

いくつかの考慮事項が最終的に、Markdown 言語サーバーが次の正しいステップであると私を納得させました。まず、かなり平凡な点ですが、Markdown ファイルのリンク診断を効率的に実装するのが非常に困難だと感じていました。vscode-docsのような大規模な Markdown ワークスペースでは、誤って拡張機能ホストを数百ミリ秒間ブロックしてしまうことがありました。これは良くない。一方、言語サーバーは独自のプロセスとして動作します。それだけでなく、言語サーバーには診断のための新しいプルモデルがあり、試してみるのが楽しみでした。

さらに、もっと崇高な理由もありました。例えば、Markdown 言語サーバーは他のエディターやツールにも役立つでしょう。これには、VS Code チームが出荷している別のエディターであるMonacoも含まれます!Markdown CLI ツールのような可能性も言うまでもありません。もし私がそのようなツールを自分で構築する時間がなかったとしても、言語サーバーを出発点として、他の誰かが構築できるかもしれません。私は VS Code の Markdown ツールに多くの労力を費やしており、このすべての作業が他の人々の利益にもなれば素晴らしいことです。

新しい言語サーバーを利用可能にすることで、Markdown ツールの改善に向けた共有の取り組みを始めることもできるかもしれません。VS Code は、オープンソースソフトウェアの多作な生産者であり利用者でもあり、私はこれらの種類のプロジェクトが提供する明確な利点を見てきました。オープンソースの Markdown 言語サーバーは他のエディターを助けるだけでなく、ひいては VS Code を最終的に助ける貢献を招くでしょう!各エディター/ツールが独自の Markdown サポートを実装するために労力を重複させるのではなく、言語サーバーは開発者を結集させ、全員に利益をもたらすより大きなプロジェクトに取り組むことができるでしょう。

これらの壮大な思索はすべて、実際に言語サーバーを構築するための計画がなければ無意味でした。すべてのリファクタリングの後でも、コードを言語サーバーに移行するのは大変な作業になるでしょう!圧倒されるように思えましたが、一度にすべてを行う必要はないと気づくまででした。VS Code Markdown 拡張機能から新しい Markdown 言語サーバーへと、一度に1つの機能を移行させながら、サーバーを段階的に構築できるのです。そして、もし私が正しく行えば、それぞれの小さな段階的な移行をコミットすることで、ユーザーが新しい言語サーバーが構築される途中でそれをテストできるようになります。理想的には、機能が拡張機能から言語サーバーに移行したことをユーザーは決して気づかないでしょう。

これは当然のことかもしれませんが、私は大規模なコード変更に対するこの種の段階的なアプローチを強く信奉するようになりました。数十万行のPRや、何ヶ月(あるいは何年!)も残るような大規模な機能ブランチはありません。代わりに、main に小さな安全な変更を多数加えるのです。すべてが計画通りに進めば、このすべての作業を締めくくるコミットは、盛り上がりに欠けるものになるはずです。これは、VS Code のコードベース全体で厳密な null チェックを段階的に使用するために私たちが取ったアプローチであり、これによって VS Code の Markdown ツールすべてを、できるだけ早く、そしてできるだけスムーズに新しい言語サーバーに移行できると感じました。

ネタバレ注意: うまくいきました!私は言語機能を一つずつ移行させました。作業を進める中で学び、必要性が明らかになったときにリファクタリングを行いました。診断機能は最後に移行された機能でした。これは、言語サーバーに移行するだけでなく、言語サーバーの新しいプル診断モデルを使用するように書き直したためです。この取り組み全体の最後のコミットでは、主に Markdown 拡張機能から不要になったコードを削除しました。そして今日、VS Code 1.70以降のバージョンを使用している場合、ほとんどすべての Markdown 言語機能が新しい言語サーバーを使用しています。

より良い Markdown ツールを共に構築する

多くの点で、過去6ヶ月間は、私がこの分野で働いてきた過去6年間よりも、VS Code の Markdown ツールにおいてより多くの進歩が見られました。今日、私たちは多くの新しいツールを出荷しており、その中にはこれまで Markdown で利用できなかったものもあります。これらの機能の多くは、Markdown のカジュアルな読者や書き手に最も恩恵をもたらしますが、他の機能は上級ユーザーにのみ評価されるでしょう。しかし、このすべての進歩にもかかわらず、Markdown ツールで何が可能かを探求し始めたばかりだと私は知っています。

Markdown Language Server について私が本当に興奮しているのは、このプロジェクトが今や VS Code だけのものではなく、それ以上に大きくなったことです。私たちの Markdown ツールを簡単に利用できるようにすることで、Markdown ツールの進化を皆で推進できることを願っています。これらのオープンソースプロジェクトは、Markdown ツールの未来を共に構築するための招待状です。貢献に興味がある場合は、新しいプロジェクトをチェックして、それらを使って何ができるかを見てください。バグ報告や機能リクエスト、もしかしたらプルリクエストも提出できます!まだ夢にも見ていないような、たくさんのスマートな Markdown 言語機能があります。一緒にそれらを構築しましょう!

ソースコードの確認や貢献に興味がある場合は、Markdown 言語サービスとサーバーを GitHub および npm で見つけることができます

ハッピーコーディング!

マット・ビアナー、@MattBierner