最速LSPクライアント lsp-bridgeを使おう

# 最速LSPクライアント lsp-bridgeを使おう

こんにちは！ メリークリスマス！ LSP使ってますか？

現在Emacsで代表的なLSPクライアントとして使われているのは[LSP Mode](https://github.com/emacs-lsp/lsp-mode)、Emacs 29から標準のLSPクライアントとしてマージされた[Eglot](https://github.com/joaotavora/eglot)があります。

そんな中、今回紹介する[lsp-bridge](https://github.com/manateelazycat/lsp-bridge)は「最速」を謳うEmacsの第三のLSPクライアントです。

https://github.com/manateelazycat/lsp-bridge

このパッケージはMELPAなどには登録されておらず、まだ開発段階の趣きがありますが、非常に快適な実装なのでこの期に紹介します。

## 特徴

> The goal of lsp-bridge is to become the fastest LSP client in Emacs, not a complete implementation of LSP protocol.

lsp-bridgeはLSPの全機能を網羅するよりも最速の実装になることを目指しています。このパッケージのアーキテクチャについては作者のmanateelazycatが[LSP-Bridge 架构设计与 LSP 协议解析](https://manateelazycat.github.io/emacs/2022/05/12/lsp-bridge.html)にまとめてれています。おもしろい文章なのでそのうち訳したいところですが、作者はEmacsとVSCodeにはLSPのパフォーマンス面で水をあけられていることに着目してlsp-bridgeを開発しました。

このパッケージはEmacsから直接LSPを通信するのではなく、PythonがEmacsとLanguage Serverのプログラムを仲立ち(bridge)して非同期に通信することでハイパフォーマンスを実現しています。入力補完についても従来は[auto-complete](https://github.com/auto-complete/auto-complete)や[Company](https://company-mode.github.io/)、近年では標準のCAPFに回帰した[Corfu](https://github.com/minad/corfu)や[Cape](https://github.com/minad/cape)も注目を集めています。しかし残念ながらLSPと非同期通信をするという観点ではCAPFは明らかに不向きであるということを[为什么lsp-bridge不用capf?](https://manateelazycat.github.io/emacs/2022/06/26/why-lsp-bridge-not-use-capf.html)で指摘しています。

> なぜ lsp-bridge が capf に基づいて構築されていないのかという質問に答える前に、質問をしたいと思います： 補完フレームワーク設計の最も重要な目標は何でしょうか？
>
> 私の理解では、すべての補完フレームワークの最も重要な目標は、「究極の補完スピードを達成し、ラグのためにプログラマーの思考を中断しない」ことです。プログラマーがコードを書くときにフリーズすると動揺し、通常の論理的思考が負の感情に影響されると、プログラミング作業を高品質に完成させることは困難になります。

このような理由により、入力補完は既存のものではなく`acm.el`というlsp-bridgeに同梱されている独自の補完フレームワークを使っています。

## インストール

先に述べたようにMELPAには登録されておらず`git clone`で管理するのが推奨です。

 1. Emacs 28以上
 2. Pythonの依存パッケージをインストール
     * `pip3 install epc orjson six`
 3. Emacs Lispパッケージをインストール
   * posframe
   * markdown-mode
   * yasnippet
 4. [lsp-bridge](https://github.com/manateelazycat/lsp-bridge)を任意のディレクトリに `git clone`

Lispパッケージは `package-install` などでさくっと入れるといいでしょう。

デフォルトでlsp-bridgeを使うときはREADMEにあるように以下のような設定をします。

```init.el
;; インストールしたディレクトリに load-path を通す
(add-to-list 'load-path "<path-to-lsp-bridge>")

(require 'yasnippet)
(yas-global-mode 1)

(require 'lsp-bridge)
(global-lsp-bridge-mode)
```

特定の言語でだけ有効化したいならばhookから `lsp-bridge-mode`を有効化しても動作します。

## Language Serverの設定

言語ごとのLanguage Serverの設定はlsp-bridgeに組み込まれています。もしあなたの使っているサーバが登録されていなければlsp-bridgeにPull Requestを送るといいでしょう。設定方法はREADMEで説明されています。

言語サーバとやりとりするのはEmacsではなくPythonのプロセスを経由します。Language Serverを起動するコマンドは単にEmacs内に設定するだけでは動きません。環境変数で`PATH`を通す必要があることに気をつけてください。

言語ごとに複数の言語サーバがインストールされていてプロジェクトごとに使い分けたいときは以下のように変数をセットします。

| 変数 | 言語 | 設定値 (文字列) |
|------|------|-------|
| `lsp-bridge-c-lsp-server` | C言語 | `"clangd"`  `"ccls"` |
| `lsp-bridge-python-lsp-server` | Python | `"pyright"` `"jedi"` `"python-ms"` `"pylsp"` |
| `lsp-bridge-php-lsp-server` | PHP | `"intelephense"` `"phpactor"` |
| `lsp-bridge-tex-lsp-server` | LaTeX | `"taxlab"` `"digestif"` |

## acm.el

`acm.el` は**Asynchronous completion menu**の略で、lsp-bridgeに同梱されている補完フレームワークです。この記事を書いている時点では、デフォルトでは以下のバックエンドが組み込まれています。

 * Tailwind CSS
 * Emacs Lisp
 * LSP
 * [citre](https://github.com/universal-ctags/citre) (Universal Ctags)
 * ファイル
 * [telega](https://github.com/zevlg/telega.el)
 * [Tabnine](https://www.tabnine.com/)
     * Tabnineクライアントは `M-x lsp-bridge-install-tabnine` でインストール
     * Tabnine Starterは無料で利用可能
     * proで課金している人は、lsp-bridgeとTabnineがインストールされた状態のバッファで `TabNine::config<RET>` と入力すると、Webブラウザで設定が開くのでログインすると有効になります
 
操作方法やカスタマイズはREADMEに載っている通りなのでご確認ください。 `acm-candidate-match-function` でマッチャーを[orderless](https://github.com/oantolin/orderless)にの関数に差し替えできるのですが、実際にはこのマッチャーを使えるバックエンドが限られてるので気をつけてください。

## 雑感

EmacsにLSPを入れたらIDEの力を手に入れて最強になるぞ！ と言われたところで言語によってはあまり情報がなかったり、どのLanguage Serverを選べばいいのかよくわからなかったり情報が少なかったり古かったりして野に放たれた状況かなと思います。LSP Modeは勝手にいい感じにしてくれそうに見えながら実はそうでもない面もあったりするので、EmacsにEglotが標準添付されることで情報が出そろってくれるとうれしいですね…！ みなさんも自分のLSP環境を軽率にシェアしてもらえると幸せになる人は増えるんじゃないでしょうか！

## EmacsConf 2022

なんと12月3日から開催される[EmacsConf 2022](https://emacsconf.org/2022/)でlsp-bridgeの発表があります。

https://emacsconf.org/2022/talks/lspbridge/

オンラインの国際カンファレンスなので時間帯が複雑なのですが、12月4日0時25分〜45分(深夜)です。

たのしみですね！