local lspKeys = function(bufnr) local tele_builtins = require('telescope.builtin') local options = { noremap = true, silent = false, buffer = bufnr } vim.keymap.set('n', ',', vim.diagnostic.goto_prev, vim.tbl_extend('error', options, { desc = 'Diag prev' })) vim.keymap.set('n', ';', vim.diagnostic.goto_next, vim.tbl_extend('error', options, { desc = 'Diag next' })) vim.keymap.set({ 'n', 'x' }, 'a', vim.lsp.buf.code_action, vim.tbl_extend('error', options, { desc = 'Code action' })) vim.keymap.set('n', 'd', tele_builtins.lsp_definitions, vim.tbl_extend('error', options, { desc = 'Definition' })) vim.keymap.set('n', 'e', vim.lsp.buf.declaration, vim.tbl_extend('error', options, { desc = 'Declaration' })) vim.keymap.set('n', 'h', function() require('pretty_hover').hover() 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', '', tele_builtins.lsp_dynamic_workspace_symbols, vim.tbl_extend('error', options, { desc = 'Workspace symbols' })) 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', 'r', tele_builtins.lsp_references, vim.tbl_extend('error', options, { desc = 'References' })) vim.keymap.set('n', '', tele_builtins.lsp_document_symbols, vim.tbl_extend('error', options, { desc = 'References' })) vim.keymap.set('n', 's', tele_builtins.lsp_dynamic_workspace_symbols, vim.tbl_extend('error', options, { desc = 'Workspace symbols' })) vim.keymap.set('n', 'v', function() tele_builtins.diagnostics({ bufnr = 0 }) end, vim.tbl_extend('error', options, { desc = 'Diagnostics' })) vim.keymap.set('n', '', 'ClangdSwitchSourceHeader', vim.tbl_extend('error', options, { desc = 'Switch Source/Header' })) end local on_attach = function(client, bufnr) local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') vim.api.nvim_buf_set_option(0, 'formatexpr', 'v:lua.vim.lsp.formatexpr()') lspKeys(bufnr) -- vim.cmd([[autocmd CursorHold lua OpenDiagFloat()]]) -- Set some keybinds conditional on server capabilities if client.server_capabilities.documentFormattingProvider then vim.keymap.set('n', 'f', function() vim.lsp.buf.format({ timeout_ms = 10000 }) end, { noremap = true, silent = false, desc = 'Format file', buffer = bufnr }) end if client.server_capabilities.documentRangeFormattingProvider then vim.keymap.set('x', 'f', function() vim.lsp.buf.format({ timeout_ms = 10000 }) end, { noremap = true, silent = false, desc = 'Format visual', buffer = bufnr }) end -- Set autocommands conditional on server_capabilities if client.server_capabilities.documentHighlightProvider then local group = vim.api.nvim_create_augroup('lsp_document_highlight', { clear = false }) vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { callback = function() vim.lsp.buf.document_highlight() end, buffer = bufnr, group = group, desc = 'Document Highlight', }) vim.api.nvim_create_autocmd('CursorMoved', { callback = function() vim.lsp.buf.clear_references() end, buffer = bufnr, group = group, desc = 'Clear All the References', }) vim.api.nvim_create_autocmd({ 'LspDetach' }, { group = group, buffer = bufnr, callback = function() vim.lsp.buf.clear_references() vim.api.nvim_clear_autocmds { group = group, buffer = bufnr } end, }) end end return { 'neovim/nvim-lspconfig', dependencies = { 'williamboman/mason.nvim', 'williamboman/mason-lspconfig.nvim', 'p00f/clangd_extensions.nvim', 'jose-elias-alvarez/null-ls.nvim', { 'folke/neodev.nvim', }, 'Fildo7525/pretty_hover', }, build = ':MasonUpdate', version = nil, branch = 'master', config = function() require('neodev').setup({ }) require('mason').setup({ ui = { border = 'rounded' } }) require('mason-lspconfig').setup({ automatic_installation = false, ensure_installed = { 'clangd', 'denols', 'neocmake', 'pyright', -- 'zk', -- No support for windows 'lua_ls', 'jsonls', -- 'groovyls', -- Doesn't work in WSL } }) local lspconfig = require('lspconfig') local capabilities = require('cmp_nvim_lsp').default_capabilities() vim.api.nvim_set_hl( 0, 'LspReferenceText', { bold = true, ctermbg = 'red', bg = '#5a524c' } ) vim.api.nvim_set_hl( 0, 'LspReferenceRead', { bold = true, ctermbg = 'red', bg = 'DarkGreen' } ) vim.api.nvim_set_hl( 0, 'LspReferenceWrite', { bold = true, ctermbg = 'red', bg = 'DarkRed' } ) local diagnostics = { Error = ' ', Warning = ' ', Information = ' ', Question = ' ', Hint = ' ', } local signs = { { name = 'DiagnosticSignError', text = diagnostics.Error }, { name = 'DiagnosticSignWarn', text = diagnostics.Warning }, { name = 'DiagnosticSignHint', text = diagnostics.Hint }, { name = 'DiagnosticSignInfo', text = diagnostics.Information }, } for _, sign in ipairs(signs) do vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) end OpenDiagFloat = function() for _, winid in pairs(vim.api.nvim_tabpage_list_wins(0)) do if vim.api.nvim_win_get_config(winid).zindex then return end end vim.diagnostic.open_float({ focusable = false, width = 80 }) end lspconfig['pyright'].setup { capabilities = capabilities, on_attach = on_attach, } lspconfig['groovyls'].setup { capabilities = capabilities, on_attach = on_attach, } -- lspconfig['cmake'].setup { -- capabilities = capabilities, -- on_attach = on_attach, -- } local configs = require('lspconfig.configs') if not configs.neocmake then configs.neocmake = { default_config = { cmd = { 'neocmakelsp', '--stdio' }, filetypes = { 'cmake' }, root_dir = function(fname) return lspconfig.util.find_git_ancestor(fname) end, single_file_support = true, -- suggested on_attach = on_attach -- on_attach is the on_attach function you defined } } lspconfig.neocmake.setup({}) end local clangd_capabilities = capabilities clangd_capabilities.textDocument.semanticHighlighting = true clangd_capabilities.offsetEncoding = { 'utf-16' } require('clangd_extensions').setup { server = { capabilities = clangd_capabilities, on_attach = on_attach, 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_dir = lspconfig.util.root_pattern( '.clangd', '.clang-tidy', '.clang-format', 'compile_flags.txt', 'configure.ac', '.git', 'build_nvim' ) }, extensions = { inlay_hints = { -- Only show inlay hints for the current line only_current_line = true, } } } lspconfig['jsonls'].setup { capabilities = capabilities, on_attach = on_attach, } lspconfig['rust_analyzer'].setup { capabilities = capabilities, on_attach = on_attach, } lspconfig['lua_ls'].setup { capabilities = capabilities, on_attach = on_attach, settings = { Lua = { workspace = { checkThirdParty = false, }, completion = { callSnippet = 'Replace' }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false, }, format = { enable = true, defaultConfig = { indent_style = 'space', indent_size = '2', quote_style = 'single', } } }, } } lspconfig['dockerls'].setup { capabilities = capabilities, on_attach = on_attach, } lspconfig['yamlls'].setup { capabilities = capabilities, on_attach = on_attach, settings = { yaml = { validate = true } } } local null_ls = require('null-ls') null_ls.setup({ sources = { null_ls.builtins.code_actions.gitsigns, -- null_ls.builtins.formatting.black, null_ls.builtins.formatting.autopep8, null_ls.builtins.formatting.prettier, null_ls.builtins.formatting.xmlformat, null_ls.builtins.diagnostics.flake8, null_ls.builtins.formatting.isort, null_ls.builtins.formatting.cmake_format, }, debug = true, on_attach = on_attach, capabilities = capabilities, }) -- vim.diagnostic.config({ virtual_text = false }) vim.diagnostic.config({ virtual_text = false, virtual_lines = false }) -- vim.diagnostic.config({ virtual_text = false, virtual_lines = { only_current_line = true } }) end, event = 'VeryLazy' }