local M = {} local Log = require "core.log" local utils = require "utils" local function lsp_highlight_document(client) if options.lsp.document_highlight == false then return -- we don't need further end -- Set autocommands conditional on server_capabilities if client.resolved_capabilities.document_highlight then vim.api.nvim_exec( [[ augroup lsp_document_highlight autocmd! * autocmd CursorHold lua vim.lsp.buf.document_highlight() autocmd CursorMoved lua vim.lsp.buf.clear_references() augroup END ]], false ) end end local function add_lsp_buffer_keybindings(bufnr) local status_ok, wk = pcall(require, "which-key") if not status_ok then return end local keys = { ["K"] = { "lua vim.lsp.buf.hover()", "Show hover" }, ["gd"] = { "lua vim.lsp.buf.definition()", "Goto Definition" }, ["gD"] = { "lua vim.lsp.buf.declaration()", "Goto declaration" }, ["gr"] = { "lua vim.lsp.buf.references()", "Goto references" }, ["gI"] = { "lua vim.lsp.buf.implementation()", "Goto Implementation" }, ["gs"] = { "lua vim.lsp.buf.signature_help()", "show signature help" }, ["gp"] = { "lua require'lsp.peek'.Peek('definition')", "Peek definition" }, ["gl"] = { "lua require'lsp.handlers'.show_line_diagnostics()", "Show line diagnostics", }, } wk.register(keys, { mode = "n", buffer = bufnr }) end function M.common_capabilities() local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities.textDocument.completion.completionItem.resolveSupport = { properties = { "documentation", "detail", "additionalTextEdits", }, } local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") if status_ok then capabilities = cmp_nvim_lsp.update_capabilities(capabilities) end return capabilities end local function select_default_formater(client) local client_formatting = client.resolved_capabilities.document_formatting or client.resolved_capabilities.document_range_formatting if client.name == "null-ls" or not client_formatting then return end Log:debug("Checking for formatter overriding for " .. client.name) local client_filetypes = client.config.filetypes or {} for _, filetype in ipairs(client_filetypes) do if not vim.tbl_isempty(lvim.lang[filetype].formatters) then Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name) client.resolved_capabilities.document_formatting = false client.resolved_capabilities.document_range_formatting = false return end end end function M.common_on_init(client, bufnr) if options.lsp.on_init_callback then options.lsp.on_init_callback(client, bufnr) Log:debug "Called lsp.on_init_callback" return end select_default_formater(client) end function M.common_on_attach(client, bufnr) if options.lsp.on_attach_callback then options.lsp.on_attach_callback(client, bufnr) Log:debug "Called lsp.on_attach_callback" end lsp_highlight_document(client) add_lsp_buffer_keybindings(bufnr) end local function bootstrap_nlsp(opts) opts = opts or {} local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") if lsp_settings_status_ok then lsp_settings.setup(opts) end end function M.get_common_opts() return { on_attach = M.common_on_attach, on_init = M.common_on_init, capabilities = M.common_capabilities(), } end function M.setup() Log:debug "Setting up LSP support" local lsp_status_ok, _ = pcall(require, "lspconfig") if not lsp_status_ok then return end for _, sign in ipairs(options.lsp.diagnostics.signs.values) do vim.fn.sign_define( sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name } ) end require("lsp.handlers").setup() if not utils.is_directory(options.lsp.templates_dir) then require("lsp.templates").generate_templates() end bootstrap_nlsp { config_home = utils.join_paths(get_config_dir(), "lsp-settings") } require("lsp.null-ls").setup() require("utils").toggle_autoformat() end return M