Emacs - Language Server Protocol

Table of Contents

Introduction

Language server protocol (LSP) offers a uniform specification between a client and a server1.

The Language Server protocol is used between a tool (the client) and a language smartness provider (the server) to integrate features like auto complete, go to definition, find all references and alike into the tool

With LSP, different clients and development tools, e.g., integrated development environment (IDE), can share a common server. Taking C/C++ for instance, various clients, e.g., Emacs, Vim, Eclipse, etc. can communicate with a common server with their own clients. For Emacs, its client is enbodied as a mode, lsp-mode2.

Maskray has provided a good summary of cquery for reference3. This post just records the installation and configuration of LSP for C/C++.

C++

cquery provides an complete LSP for C/C++/Object-C, including a LSP server and a LSP client (which depends on lsp-mode). cquery can be installed and configured following a procedure as below.

Installation

cquery

Prerequisite
pacman -S clang llvm
Install binary package
pacman -S cquery-git
Build from source codes
git clone https://github.com/jacobdufault/cquery --recursive
cd cquery
python waf configure --prefix /opt/cquery --use-system-clang
python waf build
python waf install
ln -s /opt/cquery/bin/cquery /usr/local/bin
mkdir ~/.emacs.d/cquery
cp emacs/cquery.el ~/.emacs.d/cquery
cp -r third_party /opt/cquery

lsp-mode

lsp-mode can be easily installed via ELPA.

company-lsp

For LSP, company-lsp is an optional package. It is essentially the company backend for lsp-mode, which can also be installed via ELPA.

Configuration

Add following entries into ~/.emacs.d/init.el.

(add-to-list 'load-path "~/.emacs.d/cquery")
(require 'cquery)
(add-hook 'c-mode-common-hook 'lsp-cquery-enable)
(setq cquery-cache-dir "/tmp/cquery_cache")

With LSP, two company backends, company-semantic and company-clang can be removed if used before.

(setq company-backends (delete 'company-semantic company-backends))
(setq company-backends (delete 'company-clang company-backends))

If company-lsp is installed, it can be appended in variable company-backends by adding the following entry in ~/.emacs.d/init.el.

(push 'company-lsp company-backends)

Usage

compile_commands.json

In the normal utilization of LSP, a compilation database is required4, i.e., compile_commands.json. It can be generated by a variety of tools, e.g., cmake, build ear, ninja, waf, etc.

Taking build ear for instance, which can be installed by

pacman -S bear

a compile_commands.json can be generated by compiling the target project, e.g.

bear make -j

.cquery

If compile_commands.json cannot be generated, an alternative solution is to create a file .cquery in the root directory of each project with its content as follows.

# Driver
/usr/bin/clang

# Language
-xc++
-std=c++14

# Includes
-I/opt/cquery/third_party

Provision

By default, the LSP client uses company-capf for completion, which is a company backend. Therefore, function company-complete can list the candidates for completion offered by LSP.

Key binding Function
M-. xref-find-definitions
M-, xref-pop-marker-stack
C-M-i complete-symbol
C-M-. xref-find-apropos

Footnotes: