Summary:
LSPの起源は, Microsoftによって開発されたVisual Studio Codeにさかのぼる.2016年, Microsoftは多言語対応の開発環境を効率的に構築するため, LSPを提案・実装した.当時, 各エディタはそれぞれ独自の言語機能を実装する必要があり, たとえばTypeScriptの補完機能や定義ジャンプを提供するには, Visual Studio Code, Atom, Sublime Text, IntelliJ IDEAなどのそれぞれの拡張機構に適合した実装を別々に用意する必要があった.この構造は開発・保守の負担が大きく, 対応の一貫性にも乏しかった.LSPはこれを解決するため, 言語機能の実装を「言語サーバー」に一元化し, それを任意のエディタから共通プロトコルで利用可能とする構想に基づいて設計された.
これにより, たとえばPythonのPylspやPyright, Rustのrust-analyzer, JavaのEclipse JDT Language Server, C/C++のclangdなど, 多くの言語サーバーが登場し, Visual Studio Code, Vim, Neovim, Emacs, Eclipse, IntelliJ IDEAといった多様なエディタと接続可能となった.Rustについては, 旧来のRust Language Server[RLS]が存在したが, 現在ではrust-analyzerが標準的な言語サーバーとして用いられている.
技術的には, LSPはクライアントとサーバーの間で双方向通信を行う設計となっており, メッセージはすべてJSON形式のオブジェクトで構成される.クライアントがソースコードの変更を通知すると, サーバーはその文脈に応じて補完候補や型情報, 定義箇所, 診断情報などを返す.たとえば開発者がPythonファイルでimport numpy as npと入力し, その後np.とタイプすると, クライアントはtextDocument/completionリクエストをサーバーに送信し, サーバーはarray, zeros, ones, randomなどの補完候補を提示する.また, 関数名をCtrl+クリックするとtextDocument/definitionリクエストが発行され, サーバーは定義元のファイルパスと位置情報を返す.この通信は標準入力出力, ソケット, またはWebSocketなどのチャネルを通じて行われ, 応答は非同期であり, キャンセル可能なリクエストや部分的レスポンスにも対応している.
LSPで提供される主な機能には, コード補完, 定義ジャンプ, 参照検索, リネーム, 文法チェック, ホバー情報, コードフォーマット, コードアクション, ドキュメントリンク, シグネチャヘルプなどがある.たとえばJavaScriptにおいてdocument.と入力すれば, getElementByIdやcreateElementといったDOM APIが候補として表示される.文法エラーは赤線で強調表示され, マウスホバーによってエラーの説明が提示される.定義へのジャンプにより, 関数やクラスの宣言位置に即座に移動できる.リファクタリング支援として, 変数名の一括変更や関数抽出, 未使用importの削除といった処理も可能である.
現在では, LSPはOpenJS Foundation傘下のLanguage Server Protocol Working Groupを中心とするオープンな仕様として維持・拡張されており, 50種以上のプログラミング言語に対応した言語サーバーが開発されている.主要なサーバーとしては, TypeScript/JavaScriptのtsserver, PythonのPyright・Pylsp・Jedi Language Server, Rustのrust-analyzer, Goのgopls, C/C++のclangd, JavaのEclipse JDT Language Server, C#のOmniSharp, RubyのSolargraph, PHPのIntelephense, HaskellのHaskell Language Serverなどが挙げられる.エディタ側も, Visual Studio Codeを筆頭に, Vim, Neovim, Emacs, Sublime Text, Eclipse, IntelliJ IDEA, Atom, Kate, Theia, Monaco Editor, CodeMirrorなどがLSPに対応している.
プロトコル仕様も継続的に拡張されており, 初期のコード補完や定義ジャンプといった機能に加えて, セマンティックハイライト, 型階層表示, コールヒエラルキー, テスト実行支援, デバッグ統合, コード生成の提案といった高度な機能も盛り込まれている.さらに, LSPの設計思想は他の領域にも波及し, デバッグ機能を標準化するDebug Adapter Protocol[DAP]や, テストランナー統合のためのTest Adapter Protocol[TAP]など, 周辺プロトコル群の整備も進んでいる.
LSPは, エディタとプログラミング言語の間の通信を標準化することで, 言語とツール環境の多様性を保ちつつ, 一貫した開発体験を提供する.これにより, 開発者は好みのエディタを選択しながら, 共通の言語機能を享受できるようになった.LSPは, 現代のソフトウェア開発におけるツール間分断を解消し, 言語実装とUIの疎結合化を実現するための中核的基盤として, 不可欠な技術となっている.
Mathematics is the language with which God has written the universe.