diff options
| author | Kyren223 <Kyren223@proton.me> | 2025-04-27 14:12:18 +0300 |
|---|---|---|
| committer | Kyren223 <Kyren223@proton.me> | 2025-04-27 14:12:18 +0300 |
| commit | 21107f040b1579c1139ef0ca2ce993603d24826f (patch) | |
| tree | ec72798215c80179689b9a92d1f147308771244d /.config/nvim/lsp/clangd.lua | |
| parent | 49be66e67afbbe27b4d93ec1ff39bc6c1d97e3ef (diff) | |
Massive nvim refactor, migrated from nvim-lspconfig to NVIM 0.11 lsp/*
also migrated most LSP clients to nix rather than mason
Diffstat (limited to '.config/nvim/lsp/clangd.lua')
| -rw-r--r-- | .config/nvim/lsp/clangd.lua | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/.config/nvim/lsp/clangd.lua b/.config/nvim/lsp/clangd.lua new file mode 100644 index 0000000..01ae2e1 --- /dev/null +++ b/.config/nvim/lsp/clangd.lua @@ -0,0 +1,107 @@ +-- https://clangd.llvm.org/installation.html +--- +--- - **NOTE:** Clang >= 11 is recommended! See [#23](https://github.com/neovim/nvim-lspconfig/issues/23). +--- - If `compile_commands.json` lives in a build directory, you should +--- symlink it to the root of your source tree. +--- ``` +--- ln -s /path/to/myproject/build/compile_commands.json /path/to/myproject/ +--- ``` +--- - clangd relies on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) +--- specified as compile_commands.json, see https://clangd.llvm.org/installation#compile_commandsjson + +-- https://clangd.llvm.org/extensions.html#switch-between-sourceheader +local function switch_source_header(bufnr) + local method_name = 'textDocument/switchSourceHeader' + local client = vim.lsp.get_clients({ bufnr = bufnr, name = 'clangd' })[1] + if not client then + return vim.notify( + ('method %s is not supported by any servers active on the current buffer'):format(method_name) + ) + end + local params = vim.lsp.util.make_text_document_params(bufnr) + client.request(method_name, params, function(err, result) + if err then + error(tostring(err)) + end + if not result then + vim.notify('corresponding file cannot be determined') + return + end + vim.cmd.edit(vim.uri_to_fname(result)) + end, bufnr) +end + +local function symbol_info() + local bufnr = vim.api.nvim_get_current_buf() + local clangd_client = vim.lsp.get_clients({ bufnr = bufnr, name = 'clangd' })[1] + if not clangd_client or not clangd_client.supports_method('textDocument/symbolInfo') then + return vim.notify('Clangd client not found', vim.log.levels.ERROR) + end + local win = vim.api.nvim_get_current_win() + local params = vim.lsp.util.make_position_params(win, clangd_client.offset_encoding) + clangd_client.request('textDocument/symbolInfo', params, function(err, res) + if err or #res == 0 then + -- Clangd always returns an error, there is not reason to parse it + return + end + local container = string.format('container: %s', res[1].containerName) ---@type string + local name = string.format('name: %s', res[1].name) ---@type string + vim.lsp.util.open_floating_preview({ name, container }, '', { + height = 2, + width = math.max(string.len(name), string.len(container)), + focusable = false, + focus = false, + border = 'single', + title = 'Symbol Info', + }) + end, bufnr) +end + +return { + mason = false, + cmd = { + 'clangd', + '--background-index', + '--clang-tidy', + '--header-insertion=iwyu', + '--completion-style=detailed', + '--function-arg-placeholders', + '--fallback-style=llvm', + }, + filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda', 'proto' }, + root_markers = { + '.clangd', + '.clang-tidy', + '.clang-format', + 'compile_commands.json', + 'compile_flags.txt', + 'configure.ac', -- AutoTools + '.git', + }, + init_options = { + usePlaceholders = true, + completeUnimported = true, + clangdFileStatus = true, + }, + capabilities = { + textDocument = { + completion = { + editsNearCursor = true, + }, + }, + offsetEncoding = { 'utf-8', 'utf-16' }, + }, + on_attach = function() + vim.api.nvim_buf_create_user_command(0, 'ClangdSwitchSourceHeader', function() + switch_source_header(0) + end, { desc = 'Switch between source/header' }) + + vim.api.nvim_buf_create_user_command(0, 'ClangdShowSymbolInfo', function() + symbol_info() + end, { desc = 'Show symbol info' }) + + vim.keymap.set('n', 'H', '<cmd>ClangdSwitchSourceHeader<cr>', { desc = '[H]eader and Source Switcher' }) + vim.keymap.set('n', 'K', '<cmd>lua require("pretty_hover").hover()<cr>', { desc = 'Documentation Hover' }) + -- TODO: do I need pretty_hover? maybe that's what causes issues? + end, +} |
