local map = require('my.functions').map -- only do this after the language server attaches to the current buffer local on_attach = function(client, bufnr) ---@format disable map('n', '', vim.diagnostic.goto_prev, 'Prev diagnostic', bufnr) map('n', '', vim.diagnostic.goto_next, 'Next diagnostic', bufnr) map('n', 'gD', vim.lsp.buf.declaration, 'Go to declaration', bufnr) map('n', 'gd', vim.lsp.buf.definition, 'Go to definition', bufnr) map('n', '', vim.lsp.buf.definition, 'Go to definition', bufnr) map('n', 'gi', vim.lsp.buf.implementation, 'Go to implementation', bufnr) map('n', 'gr', vim.lsp.buf.references, 'Show references', bufnr) map('n', 'K', vim.lsp.buf.hover, 'Hover', bufnr) map('i', '', vim.lsp.buf.hover, 'Hover', bufnr) map('n', 'lwa', vim.lsp.buf.add_workspace_folder, 'Add workspace folder', bufnr) map('n', 'lwr', vim.lsp.buf.remove_workspace_folder, 'Remove workspace folder', bufnr) map('n', 'lwl', function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, 'List workspace folders', bufnr) map('n', 'lr', vim.lsp.buf.rename, 'Rename symbol', bufnr) map('n', 'la', vim.lsp.buf.code_action, 'Code action', bufnr) map('n', 'lf', vim.lsp.buf.formatting, 'Format buffer', bufnr) -- highlight symbol under cursor if client.resolved_capabilities.document_highlight then vim.api.nvim_create_augroup('config_lsp', { clear = false }) vim.api.nvim_clear_autocmds({ buffer = bufnr, group = 'config_lsp', }) vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { group = 'config_lsp', buffer = bufnr, callback = vim.lsp.buf.document_highlight, }) vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { group = 'config_lsp', buffer = bufnr, callback = vim.lsp.buf.clear_references, }) -- Don't autoformat code like text vim.bo.formatoptions = vim.o.formatoptions:gsub('t', '') -- Let LSP autoformat on save require('lsp-format').on_attach(client) -- virtual text hint for parameters require ('lsp_signature').on_attach({ bind = true, handler_opts = { border = 'rounded' }, floating_window = false }, bufnr) end -- -- show help on hover -- if client.resolved_capabilities.hover then -- vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { -- group = 'config_lsp', -- buffer = bufnr, -- callback = vim.lsp.buf.hover -- }) -- end require('lsp-status').on_attach(client) end -- update client capabilities with completion plugin stuff local capabilities = require('cmp_nvim_lsp').update_capabilities( vim.lsp.protocol.make_client_capabilities()) -- progress capabilities local lsp_status = require('lsp-status') lsp_status.register_progress() capabilities = vim.tbl_extend('keep', capabilities, lsp_status.capabilities) vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( vim.lsp.handlers.hover, { border = 'rounded', width = 60, focusable = false }) -- setup servers local lspconfig = require('lspconfig') -- set up language servers that don't need any special configuration local simple_ls = { ['vscode-html-language-server'] = 'html', ['vscode-css-language-server'] = 'cssls', ['vscode-json-language-server'] = 'jsonls', ['rust_analyzer'] = 'rust_analyzer', ['gopls'] = 'gopls', ['cmake-language-server'] = 'cmake', ['yaml-language-server'] = 'yamlls', ['docker-langserver'] = 'dockerls', } for exe,ls in pairs(simple_ls) do if vim.fn.executable(exe) > 0 then lspconfig[ls].setup({ on_attach = on_attach, capabilities = capabilities }) end end if vim.fn.executable('clangd') > 0 then require("clangd_extensions").setup({ server = { cmd = { 'clangd', '--compile-commands-dir=build', '--clang-tidy', -- needs >=clangd-9 '--ranking-model=decision_forest' -- needs >=clangd-12 }, init_options = { clangdFileStatus = true }, on_attach = on_attach, capabilities = capabilities, handlers = lsp_status.extensions.clangd.setup(), }, extensions = { inlay_hints = { show_parameter_hints = false } } }) end if vim.fn.executable('lua-language-server') > 0 then lspconfig.sumneko_lua.setup({ settings = { Lua = { runtime = { version = 'LuaJIT', }, diagnostics = { globals = { 'vim' }, }, workspace = { library = vim.api.nvim_get_runtime_file('', true), }, telemetry = { enable = false, }, completion = { -- complete full function signature callSnippet = 'Replace', }, }, }, on_attach = on_attach, capabilities = capabilities }) end if vim.fn.executable('pylsp') > 0 then lspconfig.pylsp.setup({ settings = { pylsp = { } }, on_attach = on_attach, capabilities = capabilities }) end if vim.fn.executable('lemminx') > 0 then lspconfig.lemminx.setup({ filetypes = { 'xml', 'xsd', 'xsl', 'xslt', 'svg', 'gentoo-metadata' }, settings = { xml = { server = { -- path for cached XML Schemas workDir = vim.fn.stdpath('cache') .. '/lemminx' } } }, on_attach = on_attach, capabilities = capabilities }) end if vim.fn.glob('/usr/lib64/perl5/vendor_perl/5.*/Perl/LanguageServer.pm') ~= '' then lspconfig.perlls.setup({ on_attach = on_attach, capabilities = capabilities }) end if vim.fn.executable('qml-lsp') > 0 then lspconfig.qml_lsp.setup({ filetypes = { 'qml', 'qmljs' }, on_attach = on_attach, capabilities = capabilities }) end if vim.fn.executable('bash-language-server') > 0 then lspconfig.bashls.setup({ filetypes = { 'sh', 'bash', 'ebuild' }, on_attach = on_attach, capabilities = capabilities }) end if vim.fn.executable('typescript-language-server') > 0 then lspconfig.tsserver.setup({ cmd = { 'typescript-language-server', '--stdio', '--tsserver-path', 'tsserver' }, on_attach = on_attach, capabilities = capabilities }) end require('lsp-format').setup({ sync = true -- seems to be needed to not interfere with Neogit })