どうも、たくチャレ(@takuchalle)です。

Emacs Advent Calendar 2018があと1日で埋まるので、予約していた人の代わりに投稿します。11日目の記事です。

10日目は@j8takagiさんのEmacsのフォントを設定するでした!

さてみなさん、Language Server Protocol(LSP)を使ってますか。1

僕は@mattn_jpさんのブログ記事LSPを知りました。

Language Server Protocol とは

Language Server Protocolはマイクロソフトが定義しているプロトコルで、言語に依存しない形でコード解析結果をJSON-RPC形式で持っています。

下記は公式サイトからの引用です。左側がエディタのような開発ツールで、右側が各言語のLanguage Serverです。

言語に依存しない形で定義されているので、各言語がLangurage Serverを作ればLSPに準拠したエディタで追加で実装しなくても新しい言語に対応することができるようになります2一通りの言語が対応していそうです。

Emacsでいうと、go-modedart-modeみたいに各言語で実装されていた定義ジャンプやコード補完などがすべてLSPで吸収されるようになります。

使ってみる

EmacsLSPを使えるパッケージはいくつかあります。

機能が豊富そうなlsp-modeを使ってみることにします。

言語はgodartで使ってみたいと思います。

環境

$ emacs --version
GNU Emacs 26.1
Copyright (C) 2018 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.2
BuildVersion:   18C54

準備

各言語のLanguage Serverをインストールする必要があります。 goではgo-langserverを、dartではdart_language_serverをインストールしてください。

$ go get -u github.com/sourcegraph/go-langserver
$ pub global activate dart_language_server

lsp-modeREADMEに対応している言語のLanguage Serverのインストール方法が書いてあります。

Emacs client/library for the Language Server Protocol - emacs-lsp/lsp-mode

設定

まず一番コアとなるlsp-modeをインストールします。lsp-uiはドキュメントのリファレンスなどをいい感じに表示してくれます。company-lspはコード補完のバックエンドとしてcompanyを使うためのパッケージです。

そして設定したい言語のhooklspを設定すれば完了です。

;; Language Server Protocol
(package-install 'lsp-mode)
(package-install 'lsp-ui)
(package-install 'company-lsp)

(add-hook 'go-mode-hook #'lsp)
(add-hook 'dart-mode-hook #'lsp)

公式のREADMEにはuse-packageを使って細かくカスタマイズする方法がありますが、とりあえずデフォルトで使ってみたいと思います。

ツイートもしたけど、ドキュメントが占める範囲がやたらでかいけど…笑

LSPxrefと連携しているので、次のコマンドが使えます。 定義ジャンプはgtagsを使ってたんですけど、代わりにこっちを使ってみようと思います。

コマンド
定義ジャンプ xref-find-definitions
参照ジャンプ xref-find-references
ジャンプ元に戻る xref-pop-marker-stack

とりあえずgodartだけ有効にしたいので次のようにキーマップの設定しています。 グローバルのキーマップはあまり変えたくないんですけど、lsp-mode-map的なのってないんですかね…

(defun lsp-mode-init ()
  (lsp)
  (global-set-key (kbd "M-*") 'xref-pop-marker-stack)
  (global-set-key (kbd "M-.") 'xref-find-definitions)
  (global-set-key (kbd "M-/") 'xref-find-references)
  )

(add-hook 'go-mode-hook 'lsp-mode-init)
(add-hook 'dart-mode-hook 'lsp-mode-init)

まとめ

日本語でLanguage ServerEmacsで使う記事がなかったので書いてみました。

動作確認マンになりたくないというブコメをしたところなのに、動作確認マンみたいな記事を書いてしまいました…いや、これは紹介する記事だからアリだ…

とはいえ最低限の動作はこれだけでできるので、使ってるうちにここをカスタマイズしたいとかこだわりたいところが出てくると思うのでその時はまた書きたいと思います。

あまり痒いところに手が届かないようだったらeglotを使って見るのもありだな。

Emacs Advent Calendar 2018の12日目は@tadsanさんのEmacsからの安全なシェルコマンド実行でした!

参考サイト


  1. Language Server Protocol とすべきか Language Server とすべきか…
  2. 原理的には

同じカテゴリの記事