EmacsでPythonを書くとき、最初にぶつかる壁が「補完」である。
関数名や変数名を自動で提示してくれる機能だが、Emacsにおける補完の仕組みは複雑である。単に候補を出すだけではなく、背後に構文解析や通信プロトコルが存在する。
本稿では、設定やプラグインの話をする前に、その背後にある「LSP(Language Server Protocol)」という概念を理解することを目的とする。
LSP以前 ― 言語ごとに分裂していた時代
かつて、Emacsの補完は言語ごとの独自実装に依存していた。
Pythonならjedi.el、C++ならrtags、Javaならeclimといった具合である。
各パッケージが独自に解析を行い、独自のプロトコルで補完情報を渡していた。
結果として、言語が増えるたびに新しいElisp実装が必要になり、保守は煩雑を極めた。
「C言語での定義ジャンプと、Pythonでの補完が全く別物」という状況は当たり前であった。
LSPの登場 ― 共通言語の誕生
その混乱を整理したのがLSP(Language Server Protocol)である。
2016年頃、Visual Studio Codeの開発チームが「どの言語でも同じ方法で補完や解析を行える共通プロトコル」を設計した。
LSPはエディタと解析サーバのあいだの通信仕様であり、JSON-RPCを使ってやりとりを行う。
LSPを導入したエディタは、もう言語ごとの補完ロジックを持つ必要がない。
エディタは「クライアント」として統一プロトコルを喋り、解析は「サーバ」が行う。
たとえばEmacs・Vim・VSCodeがすべて同じPython解析サーバ(例:pylsp)を使える。
これにより、「解析エンジンは共通、UIは各エディタ流儀」という分業が成立した。
エディタとサーバの関係
LSPでは、以下のような通信が行われる。
Emacs → LSPサーバ:
textDocument/completion を要求
LSPサーバ → Emacs:
["print", "printf", "println"] を返す
これが補完の実体である。
エディタはただ「この位置の候補をくれ」と依頼し、サーバは解析結果を返す。
LSPはその共通の会話の文法を定めたものであり、特定エディタには依存しない。
LSPの三層構造
LSPを理解するうえで重要なのが三層構造である。
- UI層 … 候補を画面に出す。
company-modeやcorfuが該当する。 - クライアント層 … サーバと通信し、データを受け取る。
lsp-modeやeglotがここ。 - サーバ層 … 実際に言語を解析する。
pylspやpyrightなど。
Emacsではこれらが独立しており、ユーザーは好きな組み合わせを選べる。
UIを変えてもサーバは同じ、サーバを変えてもUIはそのまま――この柔軟さこそがEmacs的である。
オープンな標準としてのLSP
LSPはMicrosoft発祥ではあるが、現在はEclipse FoundationのLSP Working Groupによりオープンに策定されている。
仕様はGitHub上で公開され、誰でも提案・修正が可能である。
確かに企業の影響は残るが、プロトコル自体はフリーであり、ロックインされない。
Emacsにおいても、lsp-modeやeglotがこのプロトコルを実装し、純粋に「通信仕様」として扱っている。
まとめ
LSPとは、エディタと解析サーバをつなぐ共通語であり、
従来の「言語ごと・エディタごと」の個別実装を終わらせるものである。
これを理解すれば、EmacsがVSCodeと同じ補完精度を実現できる理由が見えてくるだろう。
次回は、このLSPをEmacsがどう扱うのか、つまりクライアント層の構造と思想を掘り下げていく。
この稿は、次の第2回「EmacsがLSPを話す ― クライアントの世界」へ続く。
