local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.documentationFormat = { 'markdown', 'plaintext' } capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities.textDocument.completion.completionItem.preselectSupport = true capabilities.textDocument.completion.completionItem.insertReplaceSupport = true capabilities.textDocument.completion.completionItem.labelDetailsSupport = true capabilities.textDocument.completion.completionItem.deprecatedSupport = true capabilities.textDocument.completion.completionItem.commitCharactersSupport = true capabilities.textDocument.completion.completionItem.tagSupport = { valueSet = { 1 } } capabilities.offsetEncoding = { 'utf-16' } capabilities.textDocument.completion.completionItem.resolveSupport = { properties = { 'documentation', 'detail', 'additionalTextEdits', }, } 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 }) 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()') -- Mappings. local opts = { noremap = true, silent = false, buffer = true } vim.keymap.set('n', ',', vim.lsp.diagnostic.goto_prev, opts) vim.keymap.set('n', ';', vim.lsp.diagnostic.goto_next, opts) vim.keymap.set('n', 'a', vim.lsp.buf.code_action, opts) vim.keymap.set('n', 'd', vim.lsp.buf.definition, opts) vim.keymap.set('n', 'e', vim.lsp.buf.declaration, opts) vim.keymap.set('n', 'h', vim.lsp.buf.hover, opts) vim.keymap.set('n', 'c', vim.lsp.buf.outgoing_calls, opts) vim.keymap.set('n', 'C', vim.lsp.buf.incoming_calls, opts) vim.keymap.set('n', 'm', vim.lsp.buf.rename, opts) local tele_builtins = require('telescope.builtin') vim.keymap.set('n', '', tele_builtins.lsp_dynamic_workspace_symbols, opts) vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, opts) vim.keymap.set('n', '', vim.lsp.buf.signature_help, opts) vim.keymap.set('n', 'r', tele_builtins.lsp_references, opts) vim.keymap.set('n', '', 'Telescope aerial', opts) vim.keymap.set('n', 'v', function() tele_builtins.diagnostics({ bufnr = 0 }) end, opts) vim.keymap.set('n', '', 'ClangdSwitchSourceHeader', opts) vim.cmd([[autocmd CursorHold lua OpenDiagFloat()]]) -- Set some keybinds conditional on server capabilities if client.server_capabilities.documentFormattingProvider then vim.keymap.set('n', 'f', vim.lsp.buf.format, opts) end if client.server_capabilities.documentRangeFormattingProvider then vim.keymap.set('v', 'f', vim.lsp.buf.range_formatting, opts) end -- Set autocommands conditional on server_capabilities if client.server_capabilities.documentHighlightProvider then vim.api.nvim_exec( [[ hi LspReferenceRead cterm=bold ctermbg=red guibg=DarkGreen hi LspReferenceWrite cterm=bold ctermbg=red guibg=DarkRed ]], false) vim.api.nvim_create_augroup("lsp_document_highlight", { clear = true }) vim.api.nvim_clear_autocmds { buffer = bufnr, group = "lsp_document_highlight" } vim.api.nvim_create_autocmd("CursorHold", { callback = vim.lsp.buf.document_highlight, buffer = bufnr, group = "lsp_document_highlight", desc = "Document Highlight", }) vim.api.nvim_create_autocmd("CursorMoved", { callback = vim.lsp.buf.clear_references, buffer = bufnr, group = "lsp_document_highlight", desc = "Clear All the References", }) end require('lsp_signature').on_attach({ bind = true, -- This is mandatory, otherwise border config won't get registered. handler_opts = { border = 'single', }, hi_parameter = 'IncSearch', }, bufnr) require("aerial").on_attach(client, bufnr) end local lsp_installer = require('nvim-lsp-installer') local servers = { 'pyright', 'cmake', 'clangd', 'jsonls', 'sumneko_lua', 'dockerls', } for _, name in pairs(servers) do local server_is_found, server = lsp_installer.get_server(name) if server_is_found then if not server:is_installed() then print('Installing ' .. name) server:install() end end end lsp_installer.on_server_ready(function(server) local opts = { on_attach = on_attach, capabilities = capabilities, } -- (optional) Customize the options passed to the server if server.name == 'clangd' then return end if server.name == 'sumneko_lua' then local lua_rtp = vim.split(package.path, ';') table.insert(lua_rtp, 'lua/?.lua') table.insert(lua_rtp, 'lua/?/init.lua') opts.settings = { Lua = { runtime = { -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) version = 'LuaJIT', -- Setup your lua path path = lua_rtp, }, diagnostics = { -- Get the language server to recognize the `vim` global globals = { 'vim', 'use' }, }, workspace = { -- Make the server aware of Neovim runtime files library = vim.api.nvim_get_runtime_file('', true), }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false, }, }, } end if server.name == 'yamlls' then opts.settings = { yaml = { validate = false } } end -- This setup() function is exactly the same as lspconfig's setup function (:help lspconfig-quickstart) server:setup(opts) vim.cmd([[ do User LspAttachBuffers ]]) end) local null_ls = require('null-ls') null_ls.setup({ sources = { null_ls.builtins.code_actions.gitsigns, null_ls.builtins.formatting.autopep8, null_ls.builtins.formatting.prettier, null_ls.builtins.diagnostics.flake8, null_ls.builtins.formatting.isort, null_ls.builtins.formatting.cmake_format, }, on_attach = on_attach, capabilities = capabilities, }) vim.diagnostic.config({ virtual_text = true }) require('clangd_extensions').setup({ server = { on_attach = on_attach, capabilities = capabilities, cmd = { 'clangd', '--compile-commands-dir=build_nvim' }, }, })