local nvim_lsp = require("lspconfig") vim.lsp.set_log_level("debug") local on_attach = function(client, bufnr) -- TODO: use vim.api.nvim_create_autocmd vim.api.nvim_exec2([[autocmd User LspDiagnosticsChanged call lightline#update()]], { output = false }) local opts = { noremap = true, silent = false } 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.type_definition()", 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.type_definition()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "k", "lua vim.diagnostic.open_float()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "e", "lua vim.lsp.buf.rename()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "r", "lua vim.lsp.buf.references()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "i", "lua vim.lsp.buf.implementation()", 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", "ci", "lua vim.lsp.buf.incoming_calls()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "co", "lua vim.lsp.buf.outgoing_calls()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "K", "lua vim.lsp.buf.hover()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "]e", 'lua vim.diagnostic.goto_next({severity="Error"})', opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "[e", 'lua vim.diagnostic.goto_prev({severity="Error"})', opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "]d", "lua vim.diagnostic.goto_next()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "[d", "lua vim.diagnostic.goto_prev()", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "cd", "lua vim.diagnostic.hide(nil, 0)", opts) -- fzf triggers: vim.api.nvim_buf_set_keymap(bufnr, "n", "fr", "References", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fi", "Implementations", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fs", "DocumentSymbols", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fw", "WorkspaceSymbols", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fc", "CodeActions", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fci", "IncomingCalls", opts) vim.api.nvim_buf_set_keymap(bufnr, "n", "fco", "OutgoingCalls", opts) require("lsp_signature").on_attach({ hint_enable = false, }) require("copilot_cmp").setup() end -- Go local capabilities = require("cmp_nvim_lsp").default_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = false capabilities.textDocument.completion.completionItem.resolveSupport = { properties = { "documentation", "detail", "additionalTextEdits", }, } nvim_lsp.gopls.setup({ settings = { gopls = { staticcheck = true, -- Disabling linksInHover may not be working as expected: linksInHover = false, usePlaceholders = true, experimentalPostfixCompletions = true, analyses = { unusedparams = true, shadow = true, unusedwrite = true, unusedresult = true, nilness = true, }, buildFlags = { "-tags=acceptance,basketapitest,graphqlapitest" } }, }, init_options = { usePlaceholders = true, }, capabilities = vim.tbl_extend( "error", capabilities, { workspace = { didChangeWatchedFiles = { dynamicRegistration = true } } } ), on_attach = on_attach, }) -- Rust nvim_lsp.rust_analyzer.setup({ capabilities = capabilities, on_attach = on_attach, settings = { ["rust-analyzer"] = { imports = { granularity = { group = "module", }, prefix = "self", }, cargo = { buildScripts = { enable = true, }, }, -- procMacro = { -- enable = false, -- }, -- diagnostics = { -- disabled = { "unresolved-proc-macro" }, -- }, }, }, }) -- Ruby nvim_lsp.solargraph.setup({ on_attach = on_attach, settings = { solargraph = { autoformat = false, formatting = false, }, }, }) -- Typescript -- https://jose-elias-alvarez.medium.com/configuring-neovims-lsp-client-for-typescript-development-5789d58ea9c nvim_lsp.ts_ls.setup({ on_attach = on_attach, }) local filetypes = { typescript = "eslint", typescriptreact = "eslint", } -- diagnosticls local linters = { eslint = { sourceName = "eslint", -- fallback to global eslint if the local is not found? -- https://github.com/creativenull/diagnosticls-configs-nvim/blob/e7d6f7e99f6b416d2aeee89314bc46fc36df7b22/lua/diagnosticls-configs/fs.lua#L20 command = "./node_modules/.bin/eslint", rootPatterns = { ".eslintrc", ".eslintrc.js" }, debounce = 100, args = { "--stdin", "--stdin-filename", "%filepath", "--format", "json" }, parseJson = { errorsRoot = "[0].messages", line = "line", column = "column", endLine = "endLine", endColumn = "endColumn", message = "${message} [${ruleId}]", security = "severity", }, securities = { [1] = "error", [2] = "warning" }, }, } nvim_lsp.diagnosticls.setup({ on_attach = on_attach, filetypes = vim.tbl_keys(filetypes), init_options = { linters = linters, filetypes = filetypes, }, }) -- Lua local runtime_path = vim.split(package.path, ";") table.insert(runtime_path, "lua/?.lua") table.insert(runtime_path, "lua/?/init.lua") nvim_lsp.lua_ls.setup({ settings = { Lua = { runtime = { version = "LuaJIT", path = runtime_path, }, diagnostics = { globals = { "vim" }, }, workspace = { library = vim.api.nvim_get_runtime_file("", true), }, telemetry = { enable = false, }, }, }, on_attach = on_attach, }) -- Bash language server -- https://github.com/bash-lsp/bash-language-server#neovim vim.api.nvim_create_autocmd("FileType", { pattern = "sh", callback = function() vim.lsp.start({ name = "bash-language-server", cmd = { "bash-language-server", "start" }, }) end, })