local M = {} local status_cmp_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") if not status_cmp_ok then return end local lspvitualtext = pcode.lsp_virtualtext or false local icons = vim.g.pcode_icons M.capabilities = vim.lsp.protocol.make_client_capabilities() M.capabilities.textDocument.completion.completionItem.snippetSupport = true M.capabilities = cmp_nvim_lsp.default_capabilities(M.capabilities) M.setup = function() local signs = { { name = "DiagnosticSignError", text = icons.diagnostics.Error }, { name = "DiagnosticSignWarn", text = icons.diagnostics.Warning }, { name = "DiagnosticSignHint", text = icons.diagnostics.Hint }, { name = "DiagnosticSignInfo", text = icons.diagnostics.Info }, } for _, sign in ipairs(signs) do vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = "" }) end local config = { virtual_text = lspvitualtext, -- disable virtual text signs = { active = signs, -- show signs }, update_in_insert = true, underline = true, severity_sort = true, float = { focusable = true, style = "minimal", border = "rounded", source = "always", header = "", prefix = "", }, } vim.diagnostic.config(config) vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "rounded", }) vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = "rounded", }) end local function attach_navic(client, bufnr) vim.g.navic_silence = true local status_ok, navic = pcall(require, "nvim-navic") if not status_ok then return end navic.attach(client, bufnr) end function FORMAT_FILTER(client) local filetype = vim.bo.filetype local n = require("null-ls") local s = require("null-ls.sources") local method = n.methods.FORMATTING local available_formatters = s.get_available(filetype, method) if #available_formatters > 0 then return client.name == "null-ls" elseif client.supports_method("textDocument/formatting") then return true else return false end end -- stylua: ignore local function lsp_keymaps(bufnr, on_save) local opts = { noremap = true, silent = true } local keymap = vim.api.nvim_buf_set_keymap keymap(bufnr, "n", "gD", "lua vim.lsp.buf.declaration()", opts) keymap(bufnr, "n", "gd", "lua vim.lsp.buf.definition()", opts) keymap(bufnr, "n", "K", "lua vim.lsp.buf.hover()", opts) keymap(bufnr, "n", "gI", "lua vim.lsp.buf.implementation()", opts) keymap(bufnr, "n", "gr", "lua vim.lsp.buf.references()", opts) keymap(bufnr, "n", "gl", "lua vim.diagnostic.open_float()", opts) keymap(bufnr, "n", "lf", "lua vim.lsp.buf.format{ async = true }", opts) keymap(bufnr, "n", "li", "LspInfo", opts) keymap(bufnr, "n", "lI", "Mason", opts) keymap(bufnr, "n", "la", "lua vim.lsp.buf.code_action()", opts) keymap(bufnr, "n", "lj", "lua vim.diagnostic.goto_next({buffer=0})", opts) keymap(bufnr, "n", "lk", "lua vim.diagnostic.goto_prev({buffer=0})", opts) keymap(bufnr, "n", "lr", "lua vim.lsp.buf.rename()", opts) keymap(bufnr, "n", "ls", "lua vim.lsp.buf.signature_help()", opts) keymap(bufnr, "n", "lq", "lua vim.diagnostic.setloclist()", opts) if on_save then local augroup = vim.api.nvim_create_augroup("LspFormatting", {}) vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) vim.api.nvim_create_autocmd("BufWritePre", { group = augroup, buffer = bufnr, callback = function() vim.lsp.buf.format({ bufnr = bufnr, timeout_ms = pcode.format_timeout_ms or 5000, filter = FORMAT_FILTER }) end, }) else vim.schedule(function() pcall(function() vim.api.nvim_clear_autocmds({ group = "LspFormatting" }) end) end) end end M.on_attach = function(client, bufnr) attach_navic(client, bufnr) if client.name == "tsserver" then client.server_capabilities.documentFormattingProvider = false end if client.name == "lua_ls" then client.server_capabilities.documentFormattingProvider = false end if client.supports_method("textDocument/inlayHint") then -- vim.lsp.inlay_hint.enable(bufnr, true) vim.lsp.inlay_hint.enable(true) end local on_save = pcode.format_on_save or false -- disable if conform active local status, _ = pcall(require, "conform") if status then on_save = false end lsp_keymaps(bufnr, on_save) local status_ok, illuminate = pcall(require, "illuminate") if not status_ok then return end illuminate.on_attach(client) end return M