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) require('which-key').register({ ['l'] = { name = 'LSP' } }) require('which-key').register({ ['lw'] = { name = 'workspace' } }) 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) if vim.fn.has('nvim-0.8.0') == 1 then map('n', 'lf', vim.lsp.buf.format, 'Format buffer', bufnr) else map('n', 'lf', vim.lsp.buf.formatting, 'Format buffer', bufnr) end -- highlight symbol under cursor local has_highlight = false if vim.fn.has('nvim-0.8.0') == 1 then if client.server_capabilities.documentHighlightProvider then has_highlight = true end else if client.resolved_capabilities.document_highlight then has_highlight = true end end if has_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.server_capabilities.hoverProvider 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 -- add completion capabilities local capabilities = require('cmp_nvim_lsp').default_capabilities() -- add progress capabilities local lsp_status = require('lsp-status') lsp_status.register_progress() capabilities = vim.tbl_extend('keep', capabilities, lsp_status.capabilities) -- opens lsp.util.open_floating_preview() -> nvim_open_win() vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'rounded', width = 60, focusable = false, -- next 2 lines do nothing, overwritten by open_floating_preview() relative = 'win', anchor = 'NE', }) -- 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', ['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 -- TODO: re-check config recommendation, looks like some things changed -- if vim.fn.executable('lua-language-server') > 0 then lspconfig.lua_ls.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', 'gentoo-init-d.sh' }, 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 }) local rt = require("rust-tools") rt.setup({ server = { on_attach = on_attach, capabilities = capabilities, settings = { ["rust-analyzer"] = { -- checkOnSave = { -- command = "clippy", -- }, -- diagnostics = { -- enable = true, -- }, } } }, })