From 0435ac87041d1c5ca9dbc0c0f0b58a970096334e Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 25 Feb 2026 09:25:22 +0100 Subject: [PATCH] feat: lua runtime, clangd config + tabsize --- .config/nvim/init.lua | 35 +++++++++-- .config/nvim/lsp/clangd-tweak.lua | 100 ++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 .config/nvim/lsp/clangd-tweak.lua diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index ed1511e..10875b2 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -1,10 +1,12 @@ +local tabsize = 2 + vim.o.number = true vim.o.relativenumber = true vim.o.wrap = false vim.o.winborder = "rounded" -vim.o.tabstop = 4 -vim.o.softtabstop = 4 -vim.o.shiftwidth = 4 +vim.o.tabstop = tabsize +vim.o.softtabstop = tabsize +vim.o.shiftwidth = tabsize vim.o.expandtab = false vim.o.smartindent = true vim.o.swapfile = false @@ -33,8 +35,8 @@ vim.lsp.config('lua_ls', { if client.workspace_folders then local path = client.workspace_folders[1].name if - path ~= vim.fn.stdpath('config') - and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc')) + path ~= vim.fn.stdpath('config') + and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc')) then return end @@ -88,6 +90,24 @@ cmp.setup({ }, { name = 'buffer' }) }) +local lsp_group = vim.api.nvim_create_augroup("MyLspKeymaps", { clear = true }) + +vim.api.nvim_create_autocmd('LspAttach', { + group = lsp_group, + callback = function(ev) + local bufnr = ev.buf + local opts = { silent = true, noremap = true, buffer = bufnr } + + vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) + vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) + vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) + vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) + vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) + vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) + vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) + end +}) + require("vague").setup { transparent = true, italic = false, @@ -100,7 +120,10 @@ vim.o.colorcolumn = "80" vim.lsp.config('lua_ls', { capabilities = capabilities, }) -vim.lsp.enable({ "lua_ls", "clangd" }) +vim.lsp.config('clangd-tweak', { + capabilities = capabilities, +}) +vim.lsp.enable({ "lua_ls", "clangd-tweak" }) vim.cmd("colorscheme vague") require 'nvim-autopairs'.setup {} diff --git a/.config/nvim/lsp/clangd-tweak.lua b/.config/nvim/lsp/clangd-tweak.lua new file mode 100644 index 0000000..217ed09 --- /dev/null +++ b/.config/nvim/lsp/clangd-tweak.lua @@ -0,0 +1,100 @@ +---@brief +--- +--- 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, client) + local method_name = 'textDocument/switchSourceHeader' + ---@diagnostic disable-next-line:param-type-mismatch + if not client or not client:supports_method(method_name) 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) + ---@diagnostic disable-next-line:param-type-mismatch + 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(bufnr, client) + local method_name = 'textDocument/symbolInfo' + ---@diagnostic disable-next-line:param-type-mismatch + if not client or not client:supports_method(method_name) 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, client.offset_encoding) + ---@diagnostic disable-next-line:param-type-mismatch + client:request(method_name, params, function(err, res) + if err or #res == 0 then + -- Clangd always returns an error, there is no 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, + title = 'Symbol Info', + }) + end, bufnr) +end + +---@class ClangdInitializeResult: lsp.InitializeResult +---@field offsetEncoding? string + +---@type vim.lsp.Config +return { + cmd = { 'clangd', '--enable-config' }, + filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' }, + root_markers = { + '.clangd', + '.clang-tidy', + '.clang-format', + 'compile_commands.json', + 'compile_flags.txt', + 'configure.ac', -- AutoTools + '.git', + }, + capabilities = { + textDocument = { + completion = { + editsNearCursor = true, + }, + }, + offsetEncoding = { 'utf-8', 'utf-16' }, + }, + ---@param init_result ClangdInitializeResult + on_init = function(client, init_result) + if init_result.offsetEncoding then + client.offset_encoding = init_result.offsetEncoding + end + end, + on_attach = function(client, bufnr) + vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdSwitchSourceHeader', function() + switch_source_header(bufnr, client) + end, { desc = 'Switch between source/header' }) + + vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdShowSymbolInfo', function() + symbol_info(bufnr, client) + end, { desc = 'Show symbol info' }) + end, +}