Linux Kernel – How to setup your editor

Last time I was working on the Linux Kernel I had a bit of trouble working with completions. But after about 4 years a lot has changed:

  • Useful completions
  • High quality hover information about words under the cursor
  • Fast inline compile warnings/errors
  • Jump to definition
  • Jump to caller
  • All with neovim and other editors

Language Servers, where were you all the time?

The most important thing are language servers now. Language servers are parsing your code and offer an interface for editors to get the information they need. This interface is standardized so you should be able to connect to different language servers but most importantly you can use a lot of different editors. Also just to mention it: This is not limited to C/C++, rust, python etc. all have language servers available.

One of the most interesting language servers in my opinion is clangd as it is packaged with clang on most distributions. It has a very easy way to be started. In the most simple setup you can start it by simply calling it clangd in your project directory.

How does it know what to do?

It looks for the widely used compile_commands.json database that describes how each file in your project is built. This includes all compile flags that you need. Most build systems are able to generate these for you or have tools available. Unfortunately Makefiles do not come with this option.

However some kernel hackers already had the need for it and created a way to generate this database. You only have to call the script scripts/clang-tools/gen_compile_commands.py in the kernel root directory and you will have a compile_commands.json.

How is it integrated with your editor?

Editor integration will be a bit different for every editor. Mainly you have to tell your editor somehow to start the language server and talk to it. So you should have a look at the documentation of your editor or simply search on stackoverflow or google.

Here is what you need for neovim

As I am a neovim user I will give some hints for neovim here. One of the lanuage server clients for neovim is autozimu/LanguageClient-neovim. The installation is documented on the github page. With a plugin manager it can be as easy as adding a plugin to your list:

Plug 'autozimu/LanguageClient-neovim', {
    \ 'branch': 'next',
    \ 'do': 'bash install.sh',
    \ }

Then you have to configure which language server to run for which filetype:

let g:LanguageClient_serverCommands = {
  \ 'cpp': ['clangd', '-j=5', '-completion-style=detailed', '-background-index', '-all-scopes-completion', '--suggest-missing-includes'],
  \ 'c': ['clangd', '-j=5',  '-completion-style=detailed', '-background-index', '-all-scopes-completion', '--suggest-missing-includes'],
  \ 'python': ['pyls'],
  \ 'rust': ['rls'],
  \ }
let g:LanguageClient_diagnosticsList = 'Disabled'

As you can see you can directly add some configuration options to it. The above snippet are my current settings for clang-11 but you may want different options. clangd --help will explain all options to you.

`g:LanguageClient_diagnosticsList’ is disabled because I didn’t want it to fill my diagnostics list. I want to use the diagnostics list as usual with neovim.

Here are some mappings that I would recommend you set up on one of your keys as they greatly simplify your life:

nnoremap <F3> :call LanguageClient#textDocument_definition()<cr>
nnoremap <F4> :call LanguageClient#textDocument_hover()<cr>
nnoremap <F5> :call LanguageClient#textDocument_references()<cr>
nnoremap <F6> :call LanguageClient_contextMenu()<CR>
  • definition jumps to the definition of the thing under your cursor.
  • hover shows you a signature or definition with comments of the thing under your cursor.
  • references shows you a list of locations where the thing under your cursor is called.

Other plugins you should have a look at

  • junegunn/fzf fuzzy find everything that clangd shows you.
  • Shougo/echodoc.vim Show the signature of the function call you are currently writing.
  • Shougo/deoplete.nvim Completer

TL;DR

  • Generate compile_commands.json by using scripts/clang-tools/gen_compile_commands.py
  • Install clang with clangd
  • Configure your editor to start and speak with clangd
  • Enjoy completions and nearly instant compile error reports in your editor

Updated: