local lsp = require('lspconfig') -- local spinner_lsp = require('spinner.lsp') local lspstatus = require('lsp-status') local my_attach = function(client, bufnr) if vim.opt.diff:get() then vim.notify('not running LSP client in diff mode') vim.lsp.stop_client() return end -- spinner_lsp.on_attach(client, bufnr) lspstatus.on_attach(client, bufnr) if client.resolved_capabilities.goto_definition then vim.keymap.set('n', '' , vim.lsp.buf.definition) vim.keymap.set('n', 'gd' , vim.lsp.buf.definition) vim.keymap.set('n', 'gR' , vim.lsp.buf.references) wk_register({ ['gd'] = {'goto definition'}, ['gR'] = {'goto references'}, }, { buffer = bufnr }) end if client.resolved_capabilities.hover then vim.keymap.set('n', 'K' , vim.lsp.buf.hover) end if client.resolved_capabilities.rename then vim.keymap.set('n', 'grr' , vim.lsp.buf.rename) wk_register({ ['grr'] = {'rename'}, }, { buffer = bufnr }) end if client.resolved_capabilities.signature_help then vim.keymap.set('n', '' , vim.lsp.buf.signature_help) -- vim.keymap.set('n', ';s ' , vim.lsp.buf.signature_help) end if client.resolved_capabilities.document_formatting then vim.keymap.set('n', 'f' , vim.lsp.buf.formatting_sync) end if client.resolved_capabilities.type_definition then vim.keymap.set('n', 'gT' , vim.lsp.buf.type_definition) wk_register({ ['gT'] = {'goto typedef'}, }, { buffer = bufnr }) end if client.resolved_capabilities.declaration then vim.keymap.set('n', 'gD' , vim.lsp.buf.declaration) wk_register({ ['gD'] = {'goto declaration'}, }, { buffer = bufnr }) end if client.resolved_capabilities.implementation then vim.keymap.set('n', 'gI' , vim.lsp.buf.implementation) wk_register({ ['gI'] = {'goto implementation'}, }, { buffer = bufnr }) end if client.resolved_capabilities.workspace_symbol then vim.keymap.set('n', 'gW' , vim.lsp.buf.workspace_symbol) wk_register({ ['gW'] = {'goto symbol'}, }, { buffer = bufnr }) end -- if client.resolved_capabilities.document_symbol then -- vim.keymap.set('n', 'g0', 'vim.lsp.buf.document_symbol') -- end if client.supports_method('textDocument/codeAction') then vim.keymap.set('n', 'ga', vim.lsp.buf.code_action) wk_register({['ga'] = {'code action'}}, {buffer = bufnr}) end end local my_exit = function(code, signal, client_id) -- spinner_lsp.on_exit(code, signal, client_id) end local capabilities = function() local caps = vim.lsp.protocol.make_client_capabilities() -- enable lsp-based snippets caps.textDocument.completion.completionItem.snippetSupport = true caps.textDocument.completion.completionItem.resolveSupport = { properties = { 'documentation', 'detail', 'additionalTextEdits', } } -- add window/workDoneProgress capability caps = vim.tbl_extend('keep', caps or {}, lspstatus.capabilities) return caps end -- overwrite codeAction handler to not ask for confirmation if only a single -- action is given local my_code_action_handler = function(_, _, actions) -- skip printing 'no code actions available' if (not actions) or #actions == 0 then return end local action_chosen if #actions == 1 then action_chosen = actions[1] else local option_strings = {} for i, action in ipairs(actions) do local title = action.title:gsub('\r\n', '\\r\\n') title = title:gsub('\n', '\\n') table.insert(option_strings, string.format('%d. %s', i, title)) end vim.ui.select(option_strings, { prompt = 'Code Actions', }, function(choice) if choice < 1 or choice > #actions then return end action_chosen = actions[choice] end) end if action_chosen.edit or type(action_chosen.command) == 'table' then if action_chosen.edit then vim.lsp.util.apply_workspace_edit(action_chosen.edit) end if type(action_chosen.command) == 'table' then vim.lsp.buf.execute_command(action_chosen.command) end else vim.lsp.buf.execute_command(action_chosen) end end local handlers = { -- ['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, {border = border}), -- ['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signatureHelp, {border = border}), ['textDocument/codeAction'] = my_code_action_handler, } -- }}} -- local lua_runtime_path = vim.split(package.path, ';') -- table.insert(lua_runtime_path, 'lua/?.lua') -- table.insert(lua_runtime_path, 'lua/?/init.lua') local servers = { ccls = { disabled = true, root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'), init_options = { compilationDatabaseDirectory = "build", index = { threads = 0 }, completion = { filterAndSort = false, }, clang = { excludeArgs = { '-frounding-math' } }, }, }, clangd = { root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'), }, elixirls = { cmd = { 'elixir-ls' }, settings = { elixirLS = { dialyzerEnabled = false, } } }, gopls = { settings = { gopls = { analyses = { -- composites = false, fieldalignment = true, nilness = true, shadow = false, unusedparams = true, unusedwrite = true, }, gofumpt = true, -- hoverKind = 'Structured', } } }, sumneko_lua = { cmd = { 'lua-language-server' }, settings = { Lua = { runtime = { version = 'LuaJIT', path = lua_runtime_path, }, diagnostics = { globals = { 'vim' }, }, -- workspace = { -- library = vim.api.nvim_get_runtime_file('', true) -- }, telemetry = { enable = false, }, }, }, }, rust_analyzer = { cmd = { 'env', 'CARGO_TARGET_DIR=/tmp', 'RUST_SRC_PATH=/usr/src/rustlib/library', 'rust-analyzer' }, settings = { ['rust-analyzer'] = { checkOnSave = { command = 'clippy' } } }, }, tsserver = { disabled = true, cmd = { 'toolbox', 'run', '--', 'sh', '-c', '. /etc/profile.d/nvm.sh && typescript-language-server --stdio' }, }, zls = { disabled = true }, zk = { disabled = true, root_dir = lsp.util.root_pattern('.zk'), }, } local setup = function() local caps = capabilities() -- spinner_lsp.setup() -- spinner_lsp.init_capabilities(caps) for server, opts in pairs(servers) do if not opts.disabled then opts = vim.tbl_extend('keep', opts, { on_attach = my_attach, on_exit = my_exit, capabilities = caps, handlers = handlers, }) lsp[server].setup(opts) end end end return { my_attach = my_attach, my_exit = my_exit, capabilities = capabilities, setup = setup, format = function(afile) local condition = not string.match(afile, "^/home/robert/devel/upstream") if condition then -- vim.notify('%#MoreMsg#󰃢%#Italic# fmt') vim.lsp.buf.formatting_seq_sync(nil, 1000) end end, }