I am using Neovim for C++ development (currently AstroNvim, and previously used LazyVim), and like it a lot. Usually I do not have any issues with the defaults for nvim-lspconfig and mason - the standard clangd
server downloaded by mason from the official LLVM release is working fine.
But when it comes to ESP32 development, the official LLVM release does not recognize the xtensa*-*-elf
target triplet. This prevents it from properly parsing the source files and whatever else is in compile_commands.json
, so I need to use Espressif's own clang release, and always have to tweak my configuration to force something like:
-- nvim-lspconfig.lua
return {
{
"neovim/nvim-lspconfig",
opts = {
servers = {
clangd = {},
-- whatever other language servers you want
},
setup = {
clangs = function(_, opts)
opts.cmd = "~/.espressif/tools/esp-clang/bin/clangd"
end
},
},
},
}
Over time this gets really annoying, especially if I need to switch back and forth before a project is complete.
So the question is, is there a way to override the global Neovim LSP configuration using some project-specific dotfile, which is recognized and parsed automatically when I start the editor inside the project's workspace? Something like .editorconfig
, but for lua-style configuration, which can "help" the lazy plugin manager configure the language servers with project-specific settings. If such mechanism exists via built-in functionality, or provided by some plugin, please also provide some hint as to how lspconfig settings can be overridden, specifically setting the clangd executable path (if it differs from the way I showed in the sample above). Thanks!
Yes, it should be possible with the nvim-config-local plugin. https://github.com/klen/nvim-config-local
Add this to the plugins
folder:
return {
"klen/nvim-config-local",
config = function()
require("config-local").setup({
-- Default options (optional)
-- Config file patterns to load (lua supported)
config_files = { ".clangd.lua", ".nvim.lua", ".nvimrc", ".exrc" },
-- Where the plugin keeps files data
hashfile = vim.fn.stdpath("data") .. "/config-local",
autocommands_create = true, -- Create autocommands (VimEnter, DirectoryChanged)
commands_create = true, -- Create commands (ConfigLocalSource, ConfigLocalEdit, ConfigLocalTrust, ConfigLocalIgnore)
silent = false, -- Disable plugin messages (Config loaded/ignored)
lookup_parents = false, -- Lookup config files in parent directories
})
end,
}
Then in your project root directory, create a file .clangd.nvim
with this content:
require("lspconfig").clangd.setup({
cmd = {
"~/.espressif/tools/esp-clang/bin/clangd",
"--pretty",
"--header-insertion=iwyu",
-- "--background-index",
-- "--suggest-missing-includes",
"--query-driver=/path/to/toolchain/bin/",
"-j=40",
"--pch-storage=memory",
"--clang-tidy",
"--compile-commands-dir=.",
},
filetypes = { "c", "cpp", "objc", "objcpp", "cuda", "proto" },
})
Tested with LazyVim (but not with your specific ESP32 clangd
though):
$ nvim --version
NVIM v0.9.1
Build type: Release
LuaJIT 2.1.0-beta3
$ cat /etc/issue
Linux Mint 21.1 Vera \n \l