树莓派4上Neovim配置clangd LSP自动补全失败求助
树莓派4上Neovim配置外部clangd失败的问题
环境说明
- 硬件:树莓派4(aarch64架构)
- 编辑器:Neovim 0.9.1,支持桌面/无头远程模式
- 插件配置:
- 插件管理器:packer.nvim
- LSP整合工具:lsp-zero.nvim,用于管理nvim-cmp、nvim-lspconfig、mason.nvim等补全相关插件
问题描述
使用:LspInstall clangd安装C++语言服务器时,提示“当前平台不受支持”——因为mason暂不支持aarch64架构的clangd预编译包。但已经通过snap包管理器在系统中安装了clangd(路径为/snap/bin/clangd),理论上可以让Neovim调用这个外部clangd,但目前配置后无法正常工作。
当前clangd的配置代码(在.lua配置文件中):
local cfg = require('lspconfig') cfg.clangd.setup({})
编辑C++源码时,:LspLog的输出片段:
[START][2023-07-09 18:19:09] LSP logging initiated [INFO][2023-07-09 18:19:09] .../vim/lsp/rpc.lua:662 "Starting RPC client" { args = {}, cmd = "/snap/bin/clangd", extra = { cwd = "/home/alexsavo/t/cproj" }} [DEBUG][2023-07-09 18:19:09] .../vim/lsp/rpc.lua:284 "rpc.send" { id = 1, jsonrpc = "2.0", method = "initialize", params = { capabilities = { offsetEncoding = { "utf-8", "utf-16" }, textDocument = { callHierarchy = { dynamicRegistration = false }, codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = false, isPreferredSupport = true, resolveSupport = { properties = { "edit" } } }, completion = { completionItem = { commitCharactersSupport = true, deprecatedSupport = true, documentationFormat = { "markdown", "plaintext" }, insertReplaceSupport = true, insertTextModeSupport = { valueSet = { 1, 2 } }, labelDetailsSupport = true, preselectSupport = true, resolveSupport = { properties = { "documentation", "detail", "additionalTextEdits", "sortText", "filterText", "insertText", "textEdit", "insertTextFormat", "insertTextMode" } }, snippetSupport = true, tagSupport = { valueSet = { 1 } } }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, completionList = { itemDefaults = { "commitCharacters", "editRange", "insertTextFormat", "insertTextMode", "data" } }, contextSupport = true, dynamicRegistration = false, editsNearCursor = true, insertTextMode = 1 }, declaration = { linkSupport = true }, definition = { linkSupport = true }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = false }, implementation = { linkSupport = true }, publishDiagnostics = { relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = false, prepareSupport = true }, semanticTokens = { augmentsSyntaxTokens = true, dynamicRegistration = false, formats = { "relative" }, multilineTokenSupport = false, overlappingTokenSupport = true, requests = { full = { delta = true }, range = false }, serverCancelSupport = false, tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" }, tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = true, willSaveWaitUntil = true }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = true }, showMessage = { messageActionItem = { additionalPropertiesSupport = false } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, didChangeWatchedFiles = { dynamicRegistration = false, relativePatternSupport = true }, semanticTokens = { refreshSupport = true }, symbol = { dynamicRegistration = false, hierarchicalWorkspaceSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, clientInfo = { name = "Neovim", version = "0.9.1" }, initializationOptions = vim.empty_dict(), processId = 2218712, rootPath = "/home/alexsavo/t/cproj", rootUri = "file:///home/alexsavo/t/cproj", trace = "off", workspaceFolders = { { name = "/home/alexsavo/t/cproj", uri = "file:///home/alexsavo/t/cproj" } } }}
从日志看,Neovim尝试启动了/snap/bin/clangd并发送了initialize请求,但后续没有任何服务器响应记录,:LspInfo显示clangd未正常连接(截图如下):
解决方法
1. 明确指定clangd路径并添加启动参数
修改clangd的配置,显式指定可执行文件路径,并添加必要的启动参数,确保snap版本的clangd能正常运行:
local lspconfig = require('lspconfig') lspconfig.clangd.setup({ cmd = { "/snap/bin/clangd", "--background-index", "--compile-commands-dir=build" }, -- 若项目用CMake,可指定compile_commands.json所在目录 root_dir = lspconfig.util.root_pattern("compile_commands.json", "CMakeLists.txt", ".git"), })
2. 检查snap clangd的权限与环境变量
snap包可能存在权限限制,确保Neovim能访问clangd的必要资源:
- 执行
snap connections clangd检查权限,确保有home接口连接 - 若需要访问系统头文件,可手动添加路径到clangd的配置,比如添加
--header-search-path=/usr/include到cmd参数中
3. 禁用mason对clangd的自动管理
因为mason无法安装aarch64的clangd,需要让lsp-zero不依赖mason安装clangd,在lsp-zero的配置中添加:
local lsp = require('lsp-zero').preset({}) lsp.skip_server_setup({'clangd'}) -- 跳过mason自动安装clangd lsp.setup() -- 手动配置clangd require('lspconfig').clangd.setup({ cmd = { "/snap/bin/clangd" }, -- 其他配置项 })
4. 验证clangd本身是否正常工作
在终端直接执行/snap/bin/clangd --version,确认能正常输出版本信息;再尝试在项目目录下运行/snap/bin/clangd,看是否有报错信息,排查服务器本身的问题。
内容的提问来源于stack exchange,提问作者Alexandr Savochkin
相关产品推荐
相关产品推荐

