local lspKeys = function(client, bufnr) local fzf = require('fzf-lua') local options = { noremap = true, silent = false, buffer = bufnr } vim.keymap.set('n', ',', vim.diagnostic.goto_prev, vim.tbl_extend('error', options, { desc = 'Diag prev' })) vim.keymap.set('n', ';', vim.diagnostic.goto_next, vim.tbl_extend('error', options, { desc = 'Diag next' })) vim.keymap.set({ 'n', 'x' }, 'a', vim.lsp.buf.code_action, vim.tbl_extend('error', options, { desc = 'Code action' })) vim.keymap.set('n', 'd', function() fzf.lsp_definitions({ jump_to_single_result = true }) end, vim.tbl_extend('error', options, { desc = 'Definition' })) vim.keymap.set('n', 'e', vim.lsp.buf.declaration, vim.tbl_extend('error', options, { desc = 'Declaration' })) vim.keymap.set('n', 'h', function() require('pretty_hover').hover() end, vim.tbl_extend('error', options, { desc = 'Hover' })) vim.keymap.set('n', 'c', vim.lsp.buf.outgoing_calls, vim.tbl_extend('error', options, { desc = 'Outgoing calls' })) vim.keymap.set('n', 'C', vim.lsp.buf.incoming_calls, vim.tbl_extend('error', options, { desc = 'Incoming calls' })) vim.keymap.set('n', 'm', vim.lsp.buf.rename, vim.tbl_extend('error', options, { desc = 'Rename' })) vim.keymap.set('n', '', fzf.lsp_live_workspace_symbols, vim.tbl_extend('error', options, { desc = 'Workspace symbols' })) vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, vim.tbl_extend('error', options, { desc = 'Type definition' })) vim.keymap.set({ 'n', 'i', 'x' }, '', vim.lsp.buf.signature_help, vim.tbl_extend('error', options, { desc = 'Signature help' })) vim.keymap.set('n', 'r', fzf.lsp_references, vim.tbl_extend('error', options, { desc = 'References' })) vim.keymap.set('n', '', fzf.lsp_document_symbols, vim.tbl_extend('error', options, { desc = 'Document symbols' })) vim.keymap.set('n', 'w', fzf.lsp_live_workspace_symbols, vim.tbl_extend('error', options, { desc = 'Workspace symbols' })) vim.keymap.set('n', 'v', vim.diagnostic.open_float, vim.tbl_extend('error', options, { desc = 'Diagnostics Float' })) vim.keymap.set('n', 'V', fzf.diagnostics_document, vim.tbl_extend('error', options, { desc = 'Diagnostics' })) vim.keymap.set('n', '', 'ClangdSwitchSourceHeader', vim.tbl_extend('error', options, { desc = 'Switch Source/Header' })) -- Set some keybinds conditional on server capabilities if client.server_capabilities.documentFormattingProvider then vim.keymap.set('n', 'f', function() vim.lsp.buf.format({ timeout_ms = 10000 }) end, { noremap = true, silent = false, desc = 'Format file', buffer = bufnr }) end if client.server_capabilities.documentRangeFormattingProvider then vim.keymap.set('x', 'f', function() vim.lsp.buf.format({ timeout_ms = 10000 }) end, { noremap = true, silent = false, desc = 'Format visual', buffer = bufnr }) end if client.supports_method('inlayHintProvider') then vim.keymap.set('n', 'i', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr }) end, { noremap = true, silent = false, desc = 'Toggle inlay hints', buffer = bufnr, }) end end local document_highlight = function(bufnr) -- Set autocommands conditional on server_capabilities local group = vim.api.nvim_create_augroup('lsp_document_highlight', { clear = false }) vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { callback = function() vim.lsp.buf.document_highlight() end, buffer = bufnr, group = group, desc = 'Document Highlight', }) vim.api.nvim_create_autocmd('CursorMoved', { callback = function() vim.lsp.buf.clear_references() end, buffer = bufnr, group = group, desc = 'Clear All the References', }) vim.api.nvim_create_autocmd({ 'LspDetach' }, { group = group, buffer = bufnr, callback = function() vim.lsp.buf.clear_references() vim.api.nvim_clear_autocmds({ group = group, buffer = bufnr, }) end, }) end local on_attach = function(client, bufnr) vim.api.nvim_set_option_value('omnifunc', 'v:lua.vim.lsp.omnifunc', { buf = 0 }) vim.api.nvim_set_option_value('formatexpr', 'v:lua.vim.lsp.formatexpr()', { buf = 0 }) lspKeys(client, bufnr) if client.server_capabilities.documentHighlightProvider then vim.keymap.set( 'n', '', function () vim.lsp.buf.clear_references() vim.lsp.buf.document_highlight() end, vim.tbl_extend('error', { noremap = true, silent = false, buffer = bufnr }, { desc = 'Document highlight' }) ) end if client.server_capabilities.documentSymbolProvider then local navic = require('nvim-navic') navic.attach(client, bufnr) end end return { 'neovim/nvim-lspconfig', dependencies = { 'williamboman/mason.nvim', 'p00f/clangd_extensions.nvim', 'Fildo7525/pretty_hover', { 'creativenull/efmls-configs-nvim', branch = 'main' }, 'SmiteshP/nvim-navic', }, version = nil, branch = 'master', config = function() local lspconfig = require('lspconfig') require('nvim-navic').setup({}) local capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()) capabilities.workspace = { didChangeWatchedFiles = { dynamicRegistration = true, }, } local diagnostics = { Error = ' ', Warning = ' ', Information = ' ', Question = ' ', Hint = ' ', } local signs = { { name = 'DiagnosticSignError', text = diagnostics.Error }, { name = 'DiagnosticSignWarn', text = diagnostics.Warning }, { name = 'DiagnosticSignHint', text = diagnostics.Hint }, { name = 'DiagnosticSignInfo', text = diagnostics.Information }, } for _, sign in ipairs(signs) do vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) end OpenDiagFloat = function() for _, winid in pairs(vim.api.nvim_tabpage_list_wins(0)) do if vim.api.nvim_win_get_config(winid).zindex then return end end vim.diagnostic.open_float({ focusable = false, width = 80 }) end require('plugins.lsp.server').setup_server(lspconfig, capabilities, on_attach) end, event = 'VeryLazy', }