Neovim の LSP 設定を見直してエラー表示を解消した話

前置き

Neovim で C言語の LSP を設定した上で自作キーボードのファームウェアの QMK Firmware(大半のコードがC言語) を編集しているのですが、下のスクリーンショットのとおり大量の “unknown type name” とか “call to undeclare” エラー表示が出ていました。

エラーが出ている様子

エラー表示はたくさん出ていますが、ファームウェアはコンパイルできますしキーボードもきちんと動作します。つまり、必要な型定義や関数定義はできており、問題はエディタにたくさんのエラーが出て精神衛生上よろしくないという問題に過ぎないのですが、思い切って対応することにしました。

対応策

結論から言いますと、プロジェクトのルートディレクトリに compile_commands.json が存在しなかったのが原因でした。

この compile_commands.json を QMK Firmware の qmk generate-compilation-database コマンドで作成したところ、下のスクリーンショットのとおり “unknown type name” とか “call to undeclare” エラー表示が消えました。

エラーを解消した様子

解決に至るまでの過程を説明しますと、まず、この問題を Slack の vim-JP で相談したら LSP の clangd の設定の問題ではないかとアドバイスされました。そこで公式リファレンス を確認したところ、“Neovim built-in LSP client” を使っている場合の設定方法が以下のとおり記載されていましたので、まずその設定を追加しました。

1local lspconfig = require('lspconfig')
2lspconfig.clangd.setup({
3  cmd = {'clangd', '--background-index', '--clang-tidy', '--log=verbose'},
4  init_options = {
5    fallbackFlags = { '-std=c++17' },
6  },
7})

次に、公式リファレンスでは clangd にソースコードを理解させるために compile_commands.json を作成するよう書かれていました。そこで compile_commands.json を作成しようとしたのですが、ここでちょっとしたトラブルに遭遇しました。

というのも、QMK Firmware のビルドは qmk compile コマンドで実施しており、make コマンドなどは使わないのですが、そういう場合の対処方法として、公式リファレンスでは Bear というツールを使うよう指示されていたためです。ただ、この目的のためだけにツールをインストールするのは面倒ですし、このツールが qmk compile コマンドを受け付けるかも分からなかったためです。

そこで色々調べていたのですが、ふと QMK Firmware の公式リファレンスの QMK CLI Commands を見たところ、qmk generate-compilation-database コマンドで compile_commands.json を作成できることが分かりました。そこでこのコマンドを実行したところ、問題なく compile_commands.json が作成できてエラー表示を解消することができました。

大した話ではありませんが、誰かの参考になるかもしれませんので、備忘録として記事を作成しました。

補足

私は clangd を mason.nvim でインストールし、mason-lspconfig.nvim 経由で nvim-lspconfig で設定していますが、nvim-lspconfig が用意しているデフォルト設定は clangd の公式リファレンスとある程度同じでした。後で上記の設定を削除してみましたがエラー表示の状況は同じでしたので、エラー表示の解消のためだけなら上記の設定は不要かもしれません。ただ、上記の設定はログのトレースや追加機能を使うための設定とのことなので、設定しても無駄にはならないかと思います。