irongit

My nvim configuration

hygo-nvim/lsp/clangd.lua
105 lines3.7 KBLua
1---@brief
2---
3--- https://clangd.llvm.org/installation.html
4---
5--- - **NOTE:** Clang >= 11 is recommended! See [#23](https://github.com/neovim/nvim-lspconfig/issues/23).
6--- - If `compile_commands.json` lives in a build directory, you should
7--- symlink it to the root of your source tree.
8--- ```
9--- ln -s /path/to/myproject/build/compile_commands.json /path/to/myproject/
10--- ```
11--- - clangd relies on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
12--- specified as compile_commands.json, see https://clangd.llvm.org/installation#compile_commandsjson
13
14-- https://clangd.llvm.org/extensions.html#switch-between-sourceheader
15local function switch_source_header(bufnr, client)
16 local method_name = "textDocument/switchSourceHeader"
17 ---@diagnostic disable-next-line:param-type-mismatch
18 if not client or not client:supports_method(method_name) then
19 return vim.notify(
20 ("method %s is not supported by any servers active on the current buffer"):format(method_name)
21 )
22 end
23 local params = vim.lsp.util.make_text_document_params(bufnr)
24 ---@diagnostic disable-next-line:param-type-mismatch
25 client:request(method_name, params, function(err, result)
26 if err then
27 error(tostring(err))
28 end
29 if not result then
30 vim.notify("corresponding file cannot be determined")
31 return
32 end
33 vim.cmd.edit(vim.uri_to_fname(result))
34 end, bufnr)
35end
36
37local function symbol_info(bufnr, client)
38 local method_name = "textDocument/symbolInfo"
39 ---@diagnostic disable-next-line:param-type-mismatch
40 if not client or not client:supports_method(method_name) then
41 return vim.notify("Clangd client not found", vim.log.levels.ERROR)
42 end
43 local win = vim.api.nvim_get_current_win()
44 local params = vim.lsp.util.make_position_params(win, client.offset_encoding)
45 ---@diagnostic disable-next-line:param-type-mismatch
46 client:request(method_name, params, function(err, res)
47 if err or #res == 0 then
48 -- Clangd always returns an error, there is no reason to parse it
49 return
50 end
51 local container = string.format("container: %s", res[1].containerName) ---@type string
52 local name = string.format("name: %s", res[1].name) ---@type string
53 vim.lsp.util.open_floating_preview({ name, container }, "", {
54 height = 2,
55 width = math.max(string.len(name), string.len(container)),
56 focusable = false,
57 focus = false,
58 title = "Symbol Info",
59 })
60 end, bufnr)
61end
62
63---@class ClangdInitializeResult: lsp.InitializeResult
64---@type vim.lsp.Config
65return {
66 cmd = { "clangd" },
67 filetypes = { "c", "cpp", "objc", "objcpp", "cuda" },
68 root_markers = {
69 ".clangd",
70 ".clang-tidy",
71 ".clang-format",
72 "Makefile",
73 "compile_commands.json",
74 "compile_flags.txt",
75 "configure.ac", -- AutoTools
76 ".git",
77 },
78 get_language_id = function(_, ftype)
79 local t = { objc = "objective-c", objcpp = "objective-cpp", cuda = "cuda-cpp" }
80 return t[ftype] or ftype
81 end,
82 capabilities = {
83 textDocument = {
84 completion = {
85 editsNearCursor = true,
86 },
87 },
88 offsetEncoding = { "utf-8", "utf-16" },
89 },
90 ---@param init_result ClangdInitializeResult
91 on_init = function(client, init_result)
92 if init_result.offsetEncoding then
93 client.offset_encoding = init_result.offsetEncoding
94 end
95 end,
96 on_attach = function(client, bufnr)
97 vim.api.nvim_buf_create_user_command(bufnr, "LspClangdSwitchSourceHeader", function()
98 switch_source_header(bufnr, client)
99 end, { desc = "Switch between source/header" })
100
101 vim.api.nvim_buf_create_user_command(bufnr, "LspClangdShowSymbolInfo", function()
102 symbol_info(bufnr, client)
103 end, { desc = "Show symbol info" })
104 end,
105}