local vim = assert(vim) local nvim_lsp = require("lspconfig") nvim_lsp.bashls.setup {} nvim_lsp.clangd.setup { filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' }, } nvim_lsp.jqls.setup {} nvim_lsp.lua_ls.setup {} nvim_lsp.ocamllsp.setup {} nvim_lsp.perlpls.setup {} nvim_lsp.rust_analyzer.setup {} nvim_lsp.verible.setup {} nvim_lsp.vimls.setup {} nvim_lsp.zls.setup {} nvim_lsp.texlab.setup {} nvim_lsp.hls.setup { settings = { haskell = { plugin = { semanticTokens = { globalOn = true } } } } } nvim_lsp.pylsp.setup { settings = { pylsp = { plugins = { pycodestyle = { enabled = false } } } } } local has_words_before = function() unpack = unpack or table.unpack local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil end local feedkey = function(key, mode) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) end -- 2. Configure CMP vim.opt.completeopt = { "menu", "menuone", "noselect" } -- Don't show matching vim.opt.shortmess:append("c") local lspkind = require("lspkind") lspkind.init({ symbol_map = { Text = "󰉿", Method = "󰊕", Function = "λ", Constructor = "", Field = "󰜢", Variable = "󰀫", Class = "󰠱", Interface = "", Module = "󰆧", Property = "󰜢", Unit = "󰑭", Value = "󰎠", Enum = "", Keyword = "󰌋", Snippet = "", Color = "󰏘", File = "󰈙", Reference = "󰈇", Folder = "󰉋", EnumMember = "", Constant = "󰏿", Struct = "󰙅", Event = "", Operator = "󰆕", TypeParameter = "τ", }, }) local cmp = require("cmp") cmp.setup({ mapping = { [""] = cmp.mapping.scroll_docs(-4, { "i", "s" }), [""] = cmp.mapping.scroll_docs(4, { "i", "s" }), [""] = cmp.mapping.close(), [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), [""] = cmp.mapping(function(fallback) cmp.select_next_item() -- Kill any outstanding snippets vim.fn["vsnip#deactivate"]() end, { "i", "s" }), [""] = cmp.mapping(function(fallback) cmp.select_prev_item() -- Kill any outstanding snippets vim.fn["vsnip#deactivate"]() end, { "i", "s" }), [""] = cmp.mapping(function(fallback) if vim.fn["vsnip#available"](1) == 1 then feedkey("(vsnip-expand-or-jump)", "") elseif cmp.visible() then cmp.mapping.confirm({ select = true })() elseif has_words_before() then cmp.complete() else fallback() -- The fallback function sends a already mapped key. In this case, it's probably ``. end end, { "i", "s" }), [""] = cmp.mapping(function() if cmp.visible() then cmp.select_prev_item() elseif vim.fn["vsnip#jumpable"](-1) == 1 then feedkey("(vsnip-jump-prev)", "") end end, { "i", "s" }), }, formatting = { format = lspkind.cmp_format({ mode = 'symbol_text', maxwidth = 50, ellipsis_char = '...', show_labelDetails = true, before = function(_, vim_item) local function split_silly_function_arguments(str) if string.len(str) == 0 or string.find(str, "[(]") == nil then return str, "" end local name_start, name_end = 1, string.find(str, "[(]") - 1 local function_name = string.sub(str, name_start, name_end) local arguments = string.sub(str, name_end + 1) return function_name, arguments end local verbosity = 1 local over_9000 = 2 if vim.bo.filetype == 'java' then verbosity = over_9000 if vim_item.kind == "Method" then local name, args = split_silly_function_arguments(vim_item.abbr) vim_item.abbr = name vim_item.menu = args .. (vim_item.menu or "") end end vim_item.abbr = string.sub(vim_item.abbr, 1, 20 * verbosity) vim_item.menu = string.sub(vim_item.menu or "", 1, 20 * verbosity) return vim_item end }) }, sources = { { name = "nvim_lsp" }, { name = "path" }, { name = "vim_vsnip" }, { name = "buffer", keyword_length = 5 }, }, sorting = { comparators = {}, -- We stop all sorting to let the lsp do the sorting }, snippet = { expand = function(args) vim.fn["vsnip#anonymous"](args.body) end, }, experimental = { native_menu = false, ghost_text = true, }, }) vim.cmd([[ augroup CmpZsh au! autocmd Filetype zsh lua require'cmp'.setup.buffer { sources = { { name = "zsh" }, } } augroup END ]]) local M = {} -- 3. Set up CiderLSP M.on_attach = function(client, bufnr) vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") if vim.lsp.formatexpr then -- Neovim v0.6.0+ only. vim.api.nvim_buf_set_option(bufnr, "formatexpr", "v:lua.vim.lsp.formatexpr") end if vim.lsp.tagfunc then vim.api.nvim_buf_set_option(bufnr, "tagfunc", "v:lua.vim.lsp.tagfunc") end local opts = { noremap = true, silent = true } vim.api.nvim_buf_set_keymap(bufnr, "n", "rn", "lua vim.lsp.buf.rename()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "ca", "lua vim.lsp.buf.code_action()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "", "lua vim.lsp.buf.hover()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "g0", "lua vim.lsp.buf.document_symbol()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gW", "lua vim.lsp.buf.workspace_symbol()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gd", "lua vim.lsp.buf.definition()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gD", "lua vim.lsp.buf.declaration()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gi", "lua vim.lsp.buf.implementation()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gr", "lua vim.lsp.buf.references()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "", "lua vim.lsp.buf.signature_help()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "g", "lua vim.lsp.buf.type_definition()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "[d", "lua vim.diagnostic.goto_prev()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "]d", "lua vim.diagnostic.goto_next()", opts) vim.api.nvim_command("augroup LSP") vim.api.nvim_command("autocmd!") if client.server_capabilities.documentHighlightProvider then vim.api.nvim_create_autocmd("CursorHold", { buffer = bufnr, callback = vim.lsp.buf.document_highlight }) vim.api.nvim_create_autocmd("CursorHoldI", { buffer = bufnr, callback = vim.lsp.buf.document_highlight }) vim.api.nvim_create_autocmd("CursorMoved", { buffer = bufnr, callback = vim.lsp.buf.buf_clear_references }) end vim.api.nvim_command("augroup END") -- When an LSP is attached, we should just set the sign column to yes in order -- to avoid the jarring behavior of it appearing and disappearing rapidly. vim.opt_local.signcolumn = 'yes' end vim.cmd[[hi DiagnosticUnderlineError gui=undercurl guisp=salmon]] vim.cmd[[hi DiagnosticUnderlineWarn gui=undercurl guisp=gold]] local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " } for type, icon in pairs(signs) do local hl = "DiagnosticSign" .. type vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" }) end return M