local lspKeys = function(client, bufnr) local options = { noremap = true, silent = false, buffer = bufnr } vim.keymap.set({ 'n', 'x' }, 'a', vim.lsp.buf.code_action, vim.tbl_extend('error', options, { desc = 'Code action' })) vim.keymap.set('n', 'e', vim.lsp.buf.declaration, vim.tbl_extend('error', options, { desc = 'Declaration' })) vim.keymap.set('n', 'h', function() vim.lsp.buf.hover({ border = 'none' }) end, vim.tbl_extend('error', options, { desc = 'Hover' })) vim.keymap.set('n', 'c', vim.lsp.buf.outgoing_calls, vim.tbl_extend('error', options, { desc = 'Outgoing calls' })) vim.keymap.set('n', 'C', vim.lsp.buf.incoming_calls, vim.tbl_extend('error', options, { desc = 'Incoming calls' })) vim.keymap.set('n', 'm', vim.lsp.buf.rename, vim.tbl_extend('error', options, { desc = 'Rename' })) vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, vim.tbl_extend('error', options, { desc = 'Type definition' })) vim.keymap.set({ 'n', 'i', 'x' }, '', vim.lsp.buf.signature_help, vim.tbl_extend('error', options, { desc = 'Signature help' })) vim.keymap.set('n', 'v', function() vim.diagnostic.open_float({ border = 'rounded' }) end, vim.tbl_extend('error', options, { desc = 'Diagnostics Float' })) vim.keymap.set('n', '', 'ClangdSwitchSourceHeader', vim.tbl_extend('error', options, { desc = 'Switch Source/Header' })) if client.supports_method('inlayHintProvider') then vim.keymap.set('n', 'i', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr }) end, { noremap = true, silent = false, desc = 'Toggle inlay hints', buffer = bufnr, }) end end return { { 'neovim/nvim-lspconfig', dependencies = { 'williamboman/mason.nvim', 'williamboman/mason-lspconfig.nvim', 'SmiteshP/nvim-navic', }, lazy = false, config = function() local servers = { basedpyright = { settings = { basedpyright = { typeCheckingMode = 'standard', }, }, }, ruff = {}, clangd = { cmd = { 'clangd', '--compile-commands-dir=build_nvim', '--query-driver', '/opt/cortex-a78-2022.08-gcc12.1-linux5.15/bin/aarch64-linux-gnu-g*', '--clang-tidy', '--background-index', '--use-dirty-headers', '--completion-style=detailed', }, root_markers = { '.clangd', '.clang-tidy', '.clang-format', 'compile_flags.txt', 'configure.ac', '.git', 'build_nvim', }, }, lua_ls = { settings = { Lua = { workspace = { checkThirdParty = false, }, completion = { callSnippet = 'Replace', }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false, }, diagnostics = { disable = { 'missing-fields' }, }, format = { enable = true, defaultConfig = { indent_style = 'space', indent_size = '2', quote_style = 'single', }, }, }, }, }, jsonls = {}, dockerls = {}, yamlls = { settings = { yaml = { validate = true, }, }, }, neocmake = {}, markdown_oxide = {}, } local ensure_installed = vim.tbl_keys(servers or {}) require('mason').setup() require('mason-lspconfig').setup({ ensure_installed = ensure_installed, }) local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) vim.lsp.config('*', { capabilities = capabilities, }) for server, settings in pairs(servers) do vim.lsp.config(server, settings) vim.lsp.enable(server) end local lsp_group = vim.api.nvim_create_augroup('UserLspAttach', { clear = true }) vim.api.nvim_create_autocmd('LspAttach', { group = lsp_group, desc = 'Set buffer‑local keymaps and options after an LSP client attaches', callback = function(args) local bufnr = args.buf local client = vim.lsp.get_client_by_id(args.data.client_id) if not client then return end lspKeys(client, bufnr) if client.server_capabilities.completionProvider then vim.bo[bufnr].omnifunc = 'v:lua.vim.lsp.omnifunc' vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr()' end if client.server_capabilities.inlayHintProvider then vim.keymap.set('n', 'i', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr }) end, { noremap = true, silent = false, desc = 'Toggle inlay hints', buffer = bufnr, }) end if client.server_capabilities.documentSymbolProvider then local navic = require('nvim-navic') navic.attach(client, bufnr) end end, }) end, }, }