1. Overview
There are a lot of packages for code development in emacs for a varity of languages, like cedet, company and others. The feature set starts from some keyword lookup for references, project handling, and code completion.The language server protocol (LSP) is powerful,generic way to integrate IDE features into editors. For emacs, there is the lsp-mode which works great. There is excellent documentation at the homepage, but I wanted to write down some condensed steps to install it.
2. Installation
The simplest way to install is to use the emacs package manager and install the package "lsp-mode".You need a LSP backend. For C there are two implementations, clangd is one of it so you might want to install that. It will be used automatically if it is available.
For a quick test, you can open a C file and execute "M-x lsp". I experienced a problem with an undefined symbol "-compose" which came from an old version of "dash" so you might want to update this package as well.
When opening a C file, emacs usually asks you to import the file as a project, you can press "i" to just import the current file or use "I" to manually set the project root directory which is often so better option. The project information are stored in the file
~/.emacs.d/.lsp-session-v1
3. Helping clangd to know about the project
clangd need to know how to compile the project and where to find include files etc. For this, a file named "compile_commands.json" must be created.There are different ways to create such a file for different build environments. You can create the manually if you want to. For cmake you can use the option "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON". For make based project you can use the tool "bear" to create the file tool. Run "bear make" to create this file.
When everything is set up, you should be able to open any C/C++ file and start the lsp integration with "M-x lsp" (when applying the config in the next section, it will be done automatically). Then tab completion should just work if you have company active. You can also try to press M-. to jump to definition of a symbol.
4. Configuration
I use the following config to automatically enable lsp:(add-hook 'c-mode-hook 'lsp-deferred) (add-hook 'c++-mode-hook 'lsp-deferred) (setq gc-cons-threshold (* 100 1024 1024) read-process-output-max (* 1024 1024) treemacs-space-between-root-nodes nil company-idle-delay 0.0 company-minimum-prefix-length 1 lsp-idle-delay 0.1) (with-eval-after-load 'lsp-mode (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration))
5. Remaining issues
I experienced the following small issues:- I got a message
Error running timer lsp--on-idle: (wrong-type-argument listp
and it looks like it comes from the breadcrumb integration. You can disable the breadcrumb by running "M-x lsp-headerline-breadcrumb-mode" or disable it completely by using the configuration(setq lsp-headerline-breadcrumb-enable nil)
- tab completion collides with yas-snipplet sometimes. I don't have a solution right now, you have to cancel the completion C-g and press tab again to get the yas-snipplet completion.
- lsp sometimes asks for system includes to be part of the project, I don't know an other workaround than blacklisting them (the dialog allows to do that).