-- 1. Configure CiderLSP local nvim_lsp = require("lspconfig") local configs = require("lspconfig.configs") local notify = require 'notify' configs.ciderlsp = { default_config = { cmd = { "/google/bin/releases/cider/ciderlsp/ciderlsp", "--tooltag=nvim-cmp", "--forward_sync_responses", "--enable_semantic_tokens", "--relay_mode=true", "--hub_addr=blade:languageservices-staging" ,"--enable_document_highlight"}, -- cmd = {'/google/bin/releases/cider/ciderlsp/ciderlsp', '--forward_sync_responses', '--enable_document_highlight'}; filetypes = { "c", "cpp", "java", "kotlin", "objc", "proto", "textproto", "go", "python", "bzl" }, root_dir = nvim_lsp.util.root_pattern("BUILD"), settings = {}, }, } local has_words_before = function() 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 -- 2. Configure CMP vim.opt.completeopt = { "menu", "menuone", "noselect" } -- Don't show the dumb matching stuff vim.opt.shortmess:append("c") local lspkind = require("lspkind") lspkind.init() local cmp = require("cmp") cmp.setup({ mapping = { [""] = cmp.mapping.scroll_docs(-4), [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping.close(), [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), [""] = cmp.mapping.confirm({ select = true }), [""] = cmp.mapping.confirm({ select = true }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif vim.fn["vsnip#available"](1) == 1 then feedkey("(vsnip-expand-or-jump)", "") 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" }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif vim.fn["vsnip#available"](1) == 1 then feedkey("(vsnip-jump-prev)", "") else fallback() -- The fallback function sends a already mapped key. In this case, it's probably ``. end end), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif vim.fn["vsnip#available"](1) == 1 then feedkey("(vsnip-expand-or-jump)", "") else fallback() -- The fallback function sends a already mapped key. In this case, it's probably ``. end end), }, sources = { { name = "nvim_lua" }, { name = "nvim_lsp" }, { name = "path" }, { name = "vim_vsnip" }, { name = 'nvim_ciderlsp', priority = 9 }, { name = "buffer", keyword_length = 5 }, }, sorting = { comparators = { cmp.config.compare.offset, cmp.config.compare.exact, cmp.config.compare.score, function(entry1, entry2) local _, entry1_under = entry1.completion_item.label:find("^_+") local _, entry2_under = entry2.completion_item.label:find("^_+") entry1_under = entry1_under or 0 entry2_under = entry2_under or 0 if entry1_under > entry2_under then return false elseif entry1_under < entry2_under then return true end end, cmp.config.compare.kind, cmp.config.compare.sort_text, cmp.config.compare.length, cmp.config.compare.order, }, }, snippet = { expand = function(args) vim.fn["vsnip#anonymous"](args.body) end, }, formatting = { format = lspkind.cmp_format({ with_text = true, maxwidth = 40, -- half max width menu = { -- nvim_ciderlsp = "[]", nvim_ciderlsp = "", buffer = "", nvim_lsp = "[CiderLSP]", nvim_lua = "[API]", path = "[path]", vim_vsnip = "[snip]", }, }), }, 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 cider_lsp_handlers = { ["textDocument/publishDiagnostics"] = vim.lsp.with( vim.lsp.diagnostic.on_publish_diagnostics, { underline = true, }) } cider_lsp_handlers["$/syncResponse"] = function(_, result, ctx) -- is_cider_lsp_attached has been setup via on_init, but hasn't received -- sync response yet. local first_fire = vim.b['is_cider_lsp_attached'] == 'no' vim.b['is_cider_lsp_attached'] = 'yes' if first_fire then notify('CiderLSP attached', 'info', {timeout=500}) require('lualine').refresh() end end cider_lsp_handlers["workspace/diagnostic/refresh"] = function(_, result, ctx) notify('result:'..result, 'info', {timeout=900}) notify('ctx:'..ctx, 'info', {timeout=900}) VPrint(result) VPrint('ctx:') VPrint(ctx) end cider_lsp_handlers['window/showMessage'] = function(_, result, ctx) local client = vim.lsp.get_client_by_id(ctx.client_id) local lvl = ({ 'ERROR', 'WARN', 'INFO', 'DEBUG', })[result.type] notify({ result.message }, lvl, { title = 'LSP | ' .. client.name, timeout = 1000, keep = function() return lvl == 'ERROR' or lvl == 'WARN' end, }) end -- 3. Set up CiderLSP local on_attach = function(client, bufnr) vim.b['is_cider_lsp_attached'] = 'no' require('lualine').refresh() 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", "L", "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", "tab split | 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", "grf", "lua vim.lsp.buf.references()", opts) -- diagnostics controls references vim.api.nvim_buf_set_keymap(bufnr, "n", "", "lua vim.lsp.buf.signature_help()", opts) vim.api.nvim_buf_set_keymap(bufnr, "i", "", "lua vim.lsp.buf.signature_help()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "gt", "lua vim.lsp.buf.type_definition()", opts) vim.api.nvim_command("augroup LSP") vim.api.nvim_command("autocmd!") if client.resolved_capabilities.document_highlight then vim.api.nvim_command("autocmd CursorHold lua vim.lsp.buf.document_highlight()") vim.api.nvim_command("autocmd CursorHoldI lua vim.lsp.buf.document_highlight()") vim.api.nvim_command("autocmd CursorMoved lua vim.lsp.util.buf_clear_references()") end vim.api.nvim_command("augroup END") end local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities()) capabilities = require('cmp_nvim_ciderlsp').update_capabilities(capabilities) capabilities['codeLens'] = {dynamicRegistration=false} -- capabilities.workspace.codeLens = {refreshSupport=true} -- capabilities.workspace.diagnostics = {refreshSupport=true} capabilities.textDocument.publishDiagnostics={ relatedInformation=true, versionSupport=false, tagSupport={ valueSet={ 1, 2 } }, codeDescriptionSupport=true, dataSupport=true, --layeredDiagnostics=true } nvim_lsp.ciderlsp.setup({ capabilities = capabilities, on_attach = on_attach, handlers = cider_lsp_handlers, })