local on_attach = function(client, bufnr) local utils = require('utils') utils.opt("o", "omnifunc", "v:lua.vim.lsp.omnifunc") -- Mappings. utils.map("n", "gD", "lua vim.lsp.buf.declaration()") utils.map("n", "gd", "lua vim.lsp.buf.definition()") utils.map("n", "gi", "lua vim.lsp.buf.implementation()") utils.map("n", "gr", "lua vim.lsp.buf.references()") utils.map("n", "K", "lua vim.lsp.buf.hover()") utils.map("n", "", "lua vim.lsp.buf.signature_help()") utils.map("n", "[d", "lua vim.diagnostic.goto_prev()") utils.map("n", "]d", "lua vim.diagnostic.goto_next()") utils.map("n", "[l", "lua vim.diagnostic.show_line_diagnostics()") utils.map("n", "]l", "lua vim.diagnostic.set_loclist()") utils.map("n", "", "lua vim.lsp.buf.code_action()") utils.map("n", "", "lua vim.lsp.buf.rename()()") utils.map("n", "", "lua vim.lsp.buf.type_definition()") -- list/add/remove workspace folders, not that I use them often utils.map("n", "wl", "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))") utils.map("n", "wa", "lua vim.lsp.buf.add_workspace_folder()") utils.map("n", "wr", "lua vim.lsp.buf.remove_workspace_folder()") -- Set formatting keybinds conditional on server capabilities if client.server_capabilities.document_formatting then utils.map('n', 'lf', 'lua vim.lsp.buf.formatting()') elseif client.server_capabilities.document_range_formatting then utils.map('n', 'lf', 'lua vim.lsp.buf.range_formatting()') end client.server_capabilities.semanticTokensProvider = nil -- Set autocommands conditional on server_capabilities if client.server_capabilities.document_highlight then vim.api.nvim_exec([[ hi LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow hi LspReferenceText cterm=bold ctermbg=red guibg=LightYellow hi LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow 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 nvim_lsp = require('lspconfig') local capabilities = vim.lsp.protocol.make_client_capabilities() -- show snippets in code completion popup capabilities.textDocument.completion.completionItem.snippetSupport = true; -- LSPs local servers = { "lua_ls", "ocamllsp", "vimls", "clangd", "rnix", } for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup {capabilities = capabilities, on_attach = on_attach} end nvim_lsp.pyright.setup({ on_attach = on_attach, }) nvim_lsp.ruff_lsp.setup({ on_attach = on_attach, capabilities = capabilities, init_options = { settings = { -- Any extra CLI arguments for `ruff` go here. args = {}, } } }) nvim_lsp.rust_analyzer.setup({ on_attach = on_attach, capabilities = capabilities, settings = { ["rust-analyzer"] = { imports = { granularity = { group = "module", }, prefix = "self", }, cargo = { buildScripts = { enable = true, }, }, procMacro = { enable = true }, checkOnSave = { command = "clippy", }, } } }) vim.g.code_action_menu_window_border = 'single' -- symbols-outline.nvim vim.g.symbols_outline = { highlight_hovered_item = true, show_guides = true, auto_preview = false, -- experimental position = 'right', keymaps = { close = "", goto_location = "", focus_location = "o", hover_symbol = "", rename_symbol = "r", code_actions = "a" }, lsp_blacklist = {} } -- LSP Enable diagnostics vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { virtual_text = false, underline = true, signs = true, update_in_insert = false }) -- Send diagnostics to quickfix list do local method = "textDocument/publishDiagnostics" local default_handler = vim.lsp.handlers[method] vim.lsp.handlers[method] = function(err, method, result, client_id, bufnr, config) default_handler(err, method, result, client_id, bufnr, config) local diagnostics = vim.diagnostic.get() local qflist = {} for bufnr, diagnostic in pairs(diagnostics) do for _, d in ipairs(diagnostic) do d.bufnr = bufnr d.lnum = d.range.start.line + 1 d.col = d.range.start.character + 1 d.text = d.message table.insert(qflist, d) end end end end