local M = {} function M.server_ready() return vim.b.lsp_server_ready end function M.lsp_diagnostic_count() if vim.diagnostic.count then return vim.diagnostic.count(0) end return {} end M.clients = {} -- store the clients for different filetype -- which can be called via vim.lsp.start_client() function M.register(filetype, cmd) M.clients[filetype] = { ['cmd'] = cmd, } end function M.setup(enabled_clients, override_client_cmds) -- {{{ local nvim_lsp = require('lspconfig') -- LspAttach and LspDetach event require nvim-0.8.0 if vim.fn.has('nvim-0.8.0') == 1 then local augroup = vim.api.nvim_create_augroup('spacevim_lsp', { clear = true }) vim.api.nvim_create_autocmd('LspAttach', { group = augroup, callback = function(args) vim.api.nvim_buf_set_var(args.buf, 'lsp_server_ready', true) end, }) vim.api.nvim_create_autocmd('LspDetach', { group = augroup, callback = function(args) vim.api.nvim_buf_set_var(args.buf, 'lsp_server_ready', false) end, }) end -- Use an on_attach function to only map the following keys -- after the language server attaches to the current buffer local on_attach = function(client, bufnr) local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end -- Enable completion triggered by buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') -- Mappings. -- local opts = { noremap=true, silent=true } -- See `:help vim.lsp.*` for documentation on any of the below functions -- buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) -- buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) -- buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) -- buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) -- buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) -- buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) -- buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) -- buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) -- buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) -- buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) -- buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) -- buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) -- buf_set_keymap('n', 'e', 'lua require("spacevim.diagnostic").show_line_diagnostics()', opts) -- buf_set_keymap('n', '[d', 'lua require("spacevim.diagnostic").goto_prev()', opts) -- buf_set_keymap('n', ']d', 'lua require("spacevim.diagnostic").goto_next()', opts) -- buf_set_keymap('n', 'q', 'lua require("spacevim.diagnostic").set_loclist()', opts) -- buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) end -- Use a loop to conveniently call 'setup' on multiple servers and -- map buffer local keybindings when the language server attaches for _, lsp in ipairs(enabled_clients) do nvim_lsp[lsp].setup({ on_attach = on_attach, flags = { debounce_text_changes = 150, }, }) end for client, override_cmd in pairs(override_client_cmds) do if type(client) == 'string' then nvim_lsp[client].setup({ cmd = override_cmd, on_attach = on_attach, flags = { debounce_text_changes = 150, }, }) end end end -- }}} local function spliteof(data, delimiter) local result = {} local from = 1 local delim_from, delim_to = string.find(data, delimiter, from) while delim_from do table.insert(result, string.sub(data, from, delim_from - 1)) from = delim_to + 1 delim_from, delim_to = string.find(data, delimiter, from) end table.insert(result, string.sub(data, from)) return result end -- -- if data.contents is a string and not empty -- silent put =a:data -- return 'markdown' -- if data function M.hover_callback(success, data) if not success then vim.api.nvim_command('call SpaceVim#util#echoWarn("Failed to retrieve hover information")') return end if type(data.contents) == 'table' then vim.api.nvim_command('leftabove split __lspdoc__') vim.api.nvim_command('set filetype=markdown.lspdoc') vim.api.nvim_command('setlocal nobuflisted') vim.api.nvim_command('setlocal buftype=nofile') vim.api.nvim_command('setlocal bufhidden=wipe') vim.api.nvim_buf_set_lines(0, 0, -1, 0, spliteof(data.contents.value, '\n')) elseif type(data.contents) == 'string' and data.contents ~= '' then -- for k, v in pairs(data) do -- print(k .. " - " .. v) -- kind is filetype -- value is contents string -- end vim.api.nvim_command('leftabove split __lspdoc__') vim.api.nvim_command('set filetype=markdown.lspdoc') vim.api.nvim_command('setlocal nobuflisted') vim.api.nvim_command('setlocal buftype=nofile') vim.api.nvim_command('setlocal bufhidden=wipe') vim.api.nvim_buf_set_lines(0, 0, -1, 0, spliteof(data.contents, '\n')) elseif type(data.contents.language) ~= 'string' and data.contents.language ~= '' then vim.api.nvim_command('leftabove split __lspdoc__') vim.api.nvim_command('set filetype=markdown.lspdoc') vim.api.nvim_command('setlocal nobuflisted') vim.api.nvim_command('setlocal buftype=nofile') vim.api.nvim_command('setlocal bufhidden=wipe') vim.api.nvim_buf_set_lines(0, 0, -1, 0, { '```' .. data.contents.language }) vim.api.nvim_buf_set_lines(0, 1, -1, 0, spliteof(data.contents, '\n')) vim.api.nvim_buf_set_lines(0, -1, -1, 0, { '```' }) elseif type(data.contents.kind) ~= 'string' and data.contents.kind ~= '' then vim.api.nvim_command('leftabove split __lspdoc__') vim.api.nvim_command('set filetype=' .. data.contents.kind .. '.lspdoc') vim.api.nvim_command('setlocal nobuflisted') vim.api.nvim_command('setlocal buftype=nofile') vim.api.nvim_command('setlocal bufhidden=wipe') vim.api.nvim_buf_set_lines(0, 0, -1, 0, spliteof(data.contents, '\n')) else print('No hover information found') end -- print(type(data)) end return M