Emacs (lsp-mode) とClangd

いまはEmacsでCのコードを書く場合はどうするのか調べてみます。

CやC++のソースコードをEmacsで書く場合、

そこで Language Server Protocol (以下、LSPと略します) の登場です。LSPについては下記が詳しいので

https://qiita.com/atsushieno/items/ce31df9bd88e98eec5c4

次の記事に lsp-clangd が取り上げられています。

ただ、そのlsp-clangdのGitHub emacs-lsp/lsp-clangd を見ると、 DEPRECATEDとなっていて lsp-mode がClangdをサポートしていると案内が出ています。

そこで M-x package-list-packages でlsp-modeをインストールします。インストール時に lsp-clients.el がダウンロードされるのですが、そのファイルにClangdを利用するのに必要な設定項目 (変数) が確認できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
;;; lsp-clients.el より

;; C-family (C, C++, Objective-C, Objective-C++)

(defcustom lsp-clients-clangd-executable "clangd"
  "The clangd executable to use.
Leave as just the executable name to use the default behavior of
finding the executable with `exec-path'."
  :group 'lsp-clangd
  :risky t
  :type 'file)

(defcustom lsp-clients-clangd-args '()
  "Extra arguments for the clangd executable."
  :group 'lsp-clangd
  :risky t
  :type '(repeat string))

(defun lsp-clients--clangd-command ()
  "Generate the language server startup command."
  `(,lsp-clients-clangd-executable ,@lsp-clients-clangd-args))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-stdio-connection
                                   'lsp-clients--clangd-command)
                  :major-modes '(c-mode c++-mode objc-mode)
                  :priority -1
                  :server-id 'clangd))

(defun lsp-clients-register-clangd ()
  (warn "This call is no longer needed. clangd is now automatically registered. Delete lsp-clients-register-clangd call from your config."))

Clangdが exec-path に含まれている場合は lsp-clients-clangd-executable に設定は不要かもしれません。私は明示的に指定しています。(末尾にinit.elに書いた設定を載せています。)

さて Clangd はLLVMが提供するツールの1つで、Homebrew経由でインストールが可能です。HomebrewでインストールしたClangdは /usr/local/opt/llvm/bin/clangd にあります。

1
$ brew install llvm

それではlspとClangdを使うためにinit.elに書いた設定を載せて終わりにします。

1
2
3
(setq lsp-clients-clangd-executable "/usr/local/opt/llvm/bin/clangd")
(require 'lsp-mode)
(add-hook 'c++-mode-hook #'lsp)