VS Code拡張開発(LSP)
拡張とLSPの関係
VS Code 拡張は [[Node.js]] 上で動くプログラムで、[[TypeScript]] で書くのが標準です。コマンドの追加や画面の装飾はエディタのAPIを直接呼べば済みます。
一方で、補完・診断(赤波線)・定義ジャンプ・ホバー説明のような言語機能は、エディタごとに書き直すと際限がありません。そこで使うのが LSP(Language Server Protocol)です。
| 役割 | 実装 | |
|---|---|---|
| クライアント | エディタ側。編集内容を送り、返ってきた結果を表示する | 拡張の中に薄く置く |
| サーバー | 言語側。解析して補完候補や診断を返す | エディタから独立した別プロセス |
両者は JSON-RPC というメッセージ形式でやり取りします。サーバーはエディタを知りません。 そのため同じサーバーを Neovim や他のエディタからも使えます。これがエディタごとの作り直しを避ける仕組みです。
サーバーが答える主なリクエスト
connection.onCompletion((params) => [
{ label: 'SUM', detail: '合計を求める関数' },
])
connection.onHover((params) => ({
contents: { kind: 'markdown', value: '**SUM(範囲)** — 合計を返す' },
}))
診断だけは向きが逆で、サーバーから一方的に送りつけます。編集のたびに解析し、問題があれば範囲と重大度を通知します。[[静的解析とリンター]] の結果をエディタ上に出す経路がこれです。
別プロセスであることの意味
サーバーが別プロセスなのは設計上の要点です。
- 重い解析でエディタが固まらない — 入力の反応とは独立して動く
- 落ちてもエディタは生き残る — サーバーだけ再起動できる
- 状態はサーバーが持つ — エディタは「何行目が変わった」しか送らない。ファイル全体の解析結果はサーバー側で保持する
裏返すと、エディタとサーバーで見ているファイル内容がずれると破綻します。編集内容の同期はプロトコルの根幹で、ここを自前で省略すると「保存するまで反映されない」といった不具合になります。
実務での注意点
- 設定のスキーマを書く — 拡張の設定項目は
package.jsonに宣言します。書式は [[JSON Schema]] 相当で、これが設定画面の入力補助になります - 起動条件を絞る — 全ファイルで起動する拡張は体感を悪くします。対象の言語やファイル名に限定します
- デバッグは2プロセス — クライアントとサーバーを別々にアタッチします。サーバー側のログは専用の出力チャネルへ出します
- [[ドキュメンテーション]] が普及を決める — 拡張は使い方が分からなければ使われません。設定項目とコマンドの一覧は README に必ず載せます
初学者向けポイント
- まずは診断だけを返すサーバーから始めると全体像が掴めます。補完や定義ジャンプは後から足せます
- 位置の指定は0始まりの行・桁です。エディタの表示(1始まり)とずれるため、範囲がひとつずれる不具合が起きがちです
- ファイルの識別子はパスではなく URI です。Windows のパス区切りをそのまま渡すと一致しません
関連技術とのつながり
- [[TypeScript]] — 拡張とサーバーの標準的な記述言語
- [[Node.js]] — 拡張の実行環境
- [[静的解析とリンター]] — 解析結果を診断としてエディタに出す経路
- [[JSON Schema]] — 設定項目の宣言と入力補助の土台
- [[ドキュメンテーション]] — 設定とコマンドを伝えないと拡張は使われない
Q: LSPでサーバーをエディタから独立させる利点はどれ?
- [ ] エディタの起動が速くなる
- [x] 同じサーバーを別のエディタからも使え、作り直しを避けられる
- [ ] 拡張の配布サイズが小さくなる
解説: サーバーはエディタを知らないため、プロトコルに対応した他のエディタからも利用できます。
Q: 診断(赤波線)のやり取りの向きはどれ?
- [ ] エディタが要求し、サーバーが応答する
- [x] サーバーが解析結果を一方的に通知する
- [ ] エディタが自分で解析して表示する
解説: 編集のたびにサーバーが解析し、問題の範囲と重大度を通知します。
Q: 言語サーバーを別プロセスにすることで避けられる問題はどれ?
- [x] 重い解析でエディタの入力が固まること
- [ ] ファイルの文字コードが化けること
- [ ] 設定項目が増えること
解説: 解析が独立して動くため入力の反応を妨げず、サーバーが落ちてもエディタは生き残ります。