local misc = require("core.misc") local map, include = misc.map, misc.include local M = {} -- TODO: find a way to make the qflist current item be the one closest to the -- cursor whenever we open it local function on_list(opts) vim.fn.setqflist({}, "r", opts) if #opts.items > 1 then vim.cmd.copen() end vim.cmd(".cc! 1") end ---@type vim.lsp.util.open_floating_preview.Opts local popup_opts = { border = vim.g.border_style } ---@type vim.lsp.buf.hover.Opts ---@diagnostic disable-next-line: assign-type-mismatch local hover_opts = vim.tbl_deep_extend("force", popup_opts, {}) ---@type vim.lsp.buf.signature_help.Opts ---@diagnostic disable-next-line: assign-type-mismatch local signature_opts = vim.tbl_deep_extend("force", popup_opts, {}) ---@type vim.lsp.ListOpts local list_opts = { on_list = on_list } ---@type vim.lsp.LocationOpts ---@diagnostic disable-next-line: assign-type-mismatch local location_opts = vim.tbl_deep_extend("force", list_opts, {}) --- setup basic options on lsp attach ---@param bufnr number buffer number local function attach(bufnr) local opts = { buffer = bufnr, nowait = true } -- LSP actions map("n", "K", function() vim.lsp.buf.hover(hover_opts) end, opts) map("n", "gd", function() vim.lsp.buf.definition(location_opts) end, opts) map("n", "gD", function() vim.lsp.buf.declaration(location_opts) end, opts) map("n", "gi", function() vim.lsp.buf.implementation(location_opts) end, opts) map("n", "gy", function() vim.lsp.buf.type_definition(location_opts) end, opts) map("n", "gr", function() vim.lsp.buf.references(nil, list_opts) end, opts) map("n", "", function() vim.lsp.buf.signature_help(signature_opts) end, opts) map("n", { "r", "" }, vim.lsp.buf.rename, opts) map("n", { "gA", "" }, vim.lsp.buf.code_action, { buffer = bufnr, desc = "check code actions", }) -- Diagnostics map("n", "[d", function() if not vim.fn.has("nvim-0.11") then vim.diagnostic.goto_prev() else vim.diagnostic.jump({ count = -1 }) end end, opts) map("n", "]d", function() if not vim.fn.has("nvim-0.11") then vim.diagnostic.goto_next() else vim.diagnostic.jump({ count = 1 }) end end, opts) -- map("n", "qD", vim.diagnostic.setqflist, opts) end function M.setup() vim.diagnostic.config { virtual_text = false, virtual_lines = { only_current_line = true, }, update_in_insert = false, underline = true, severity_sort = true, signs = { text = { [vim.diagnostic.severity.ERROR] = "x", [vim.diagnostic.severity.WARN] = "!", [vim.diagnostic.severity.INFO] = "i", [vim.diagnostic.severity.HINT] = "h", } } } if not vim.fn.has("nvim-0.11") then vim.lsp.handlers["textDocument/hover"] = vim.lsp.with( vim.lsp.handlers.hover, { border = vim.g.border_style }) vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with( vim.lsp.handlers.signature_help, { border = vim.g.border_style }) end -- set default capabilities include("lspconfig.util").default_config.capabilities = M.capabilities -- run whenever a client attaches vim.api.nvim_create_autocmd("LspAttach", { callback = function(event) -- map keybinds attach(event.buf) end }) end -- FIXME: I don"t like this way of doing things, there has to be a better way --- capabilities that are to be used in lsp servers, for those setup through --- lspconfig, this is already set as the default. Incase there is a server --- not setup through lspconfig this function may be called to receive the --- proper capabilities data. M.capabilities = vim.lsp.protocol.make_client_capabilities() --- add capabilities to the default capabilities string ---@param new_capabilities lsp.ClientCapabilities function M.add_capabilities(new_capabilities) vim.tbl_deep_extend("force", M.capabilities, new_capabilities) end return M