return { 'nvim-lspconfig', event = { 'BufReadPost', 'BufWritePost', 'BufNewFile' }, before = function() require('lz.n').trigger_load('blink.cmp') end, after = function() local i = require('icons') local opts = { ---@class vim.diagnostic.Opts diagnostics = { underline = true, update_in_insert = false, virtual_text = { spacing = 4, source = 'if_many', prefix = function(diagnostic) for d, icon in pairs(i.diagnostics) do if diagnostic.severity == vim.diagnostic.severity[d:upper()] then return icon end end return '●' end, }, severity_sort = true, signs = { text = { [vim.diagnostic.severity.ERROR] = i.diagnostics.Error, [vim.diagnostic.severity.WARN] = i.diagnostics.Warn, [vim.diagnostic.severity.HINT] = i.diagnostics.Hint, [vim.diagnostic.severity.INFO] = i.diagnostics.Info, }, }, }, capabilities = { workspace = { fileOperations = { didRename = true, willRename = true, }, }, }, servers = { lua_ls = { settings = { Lua = { workspace = { checkThirdParty = false }, codeLens = { enable = true }, completion = { callSnippet = 'Replace' }, doc = { privateName = { '^_' } }, hint = { enable = true, setType = false, paramType = true, paramName = 'Disable', semicolon = 'Disable', arrayIndex = 'Disable', }, }, }, }, }, } -- Codelens. vim.api.nvim_create_autocmd('User', { pattern = 'LspSupportsMethod', callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) local buffer = args.data.buffer if client and args.data.method == 'textDocument/codeLens' then vim.lsp.codelens.refresh() vim.api.nvim_create_autocmd( { 'BufEnter', 'CursorHold', 'InsertLeave' }, { buffer = buffer, callback = vim.lsp.codelens.refresh, } ) end end, }) -- Diagnostics. vim.diagnostic.config(vim.deepcopy(opts.diagnostics)) -- Server setup. local has_blink, blink = pcall(require, 'blink.cmp') local capabilities = vim.tbl_deep_extend( 'force', {}, vim.lsp.protocol.make_client_capabilities(), has_blink and blink.get_lsp_capabilities() or {}, opts.capabilities ) local function setup(server) local server_opts = vim.tbl_deep_extend('force', { capabilities = vim.deepcopy(capabilities), }, opts.servers[server] or {}) if server_opts.enabled == false then return end if opts.setup and opts.setup[server] then if opts.setup[server](server, server_opts) then return end end require('lspconfig')[server].setup(server_opts) end for server, server_opts in pairs(opts.servers) do if server_opts.enabled ~= false then setup(server) end end -- Set keymaps. vim.api.nvim_create_autocmd('LspAttach', { callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) if not client then return end local set = vim.keymap.set set('n', 'cl', 'LspInfo', { desc = 'lsp info' }) set('n', 'gD', vim.lsp.buf.declaration, { desc = 'declaration' }) set('n', 'gI', vim.lsp.buf.implementation, { desc = 'implementation' }) set( 'n', 'gr', vim.lsp.buf.references, { desc = 'references', nowait = true } ) set( 'n', 'gy', vim.lsp.buf.type_definition, { desc = 'type definition' } ) set('n', 'K', function() return vim.lsp.buf.hover() end, { desc = 'hover' }) if client.supports_method('textDocument/codeAction') then set( { 'n', 'v' }, 'ca', vim.lsp.buf.code_action, { desc = 'code action' } ) end if client.supports_method('textDocument/codeLens') then set( { 'n', 'v' }, 'cc', vim.lsp.codelens.run, { desc = 'run codelens' } ) set( 'n', 'cC', vim.lsp.codelens.refresh, { desc = 'refresh & display codelens' } ) end if client.supports_method('textDocument/definition') then set('n', 'gd', vim.lsp.buf.definition, { desc = 'definition' }) end if client.supports_method('textDocument/documentHighlight') then if Snacks.words.is_enabled() then set('n', '', function() Snacks.words.jump(vim.v.count1, true) end, { desc = 'next reference' }) set('n', '', function() Snacks.words.jump(-vim.v.count1, true) end, { desc = 'prev reference' }) set('n', ']]', function() Snacks.words.jump(vim.v.count1) end, { desc = 'next reference' }) set('n', '[[', function() Snacks.words.jump(-vim.v.count1) end, { desc = 'prev reference' }) end end if client.supports_method('textDocument/rename') then set('n', 'cr', vim.lsp.buf.rename, { desc = 'rename' }) end if client.supports_method('textDocument/signatureHelp') then set('i', '', function() return vim.lsp.buf.signature_help() end, { desc = 'signature help' }) set('n', 'gK', function() vim.lsp.buf.signature_help() end, { desc = 'signature help' }) end if client.supports_method('workspace/didRenameFiles') or client.supports_method('workspace/willRenameFiles') then set('n', 'cR', function() Snacks.rename.rename_file() end, { desc = 'rename file' }) end end, }) end, }