local lsp_lines = require("lsp_lines") lsp_lines.setup() -- Disable virtual_text since it's redundant due to lsp_lines. vim.diagnostic.config({ virtual_text = false, }) -- The nvim-cmp almost supports LSP's capabilities so You should advertise it to LSP servers.. local capabilities = require("cmp_nvim_lsp").default_capabilities() -- Tell the server the capability of foldingRange, -- Neovim hasn't added foldingRange to default capabilities, users must add it manually capabilities.textDocument.foldingRange = { dynamicRegistration = false, lineFoldingOnly = true, } -- NOTE https://github.com/neovim/neovim/pull/22405 capabilities.didChangeWatchedFiles = { dynamicRegistration = true, } local lspconfig = require("lspconfig") local on_attach_def = function(client, bufnr) require("which-key").register({ K = { function() local winid = require("ufo").peekFoldedLinesUnderCursor() if not winid then vim.lsp.buf.hover() end end, "Hover", }, [""] = { c = { name = "code", c = { require("actions-preview").code_actions, "Code action", mode = { "v", "n" } }, r = { function() return ":IncRename " .. vim.fn.expand("") end, "Rename", expr = true, }, f = { function() vim.lsp.buf.format({ async = true }) end, "Format (lsp)", mode = { "n", "v" }, }, }, t = { l = { function() lsp_lines.toggle() if vim.diagnostic.is_disabled() then vim.diagnostic.enable() else vim.diagnostic.disable() end end, "LSP lines", }, i = { function() vim.lsp.inlay_hint.enable(bufnr, not vim.lsp.inlay_hint.is_enabled(bufnr)) end, "LSP inlay hints", }, }, }, g = { d = { function() require("telescope.builtin").lsp_definitions({ reuse_win = true }) end, "Goto definition", }, t = { function() require("telescope.builtin").lsp_type_definitions({ reuse_win = true }) end, "Goto type definition", }, r = { "Telescope lsp_references", "Goto references" }, D = { vim.lsp.buf.declaration, "Goto declaration" }, I = { "Telescope lsp_implementations", "Goto implementation" }, K = { vim.lsp.buf.signature_help, "Signature help" }, }, ["["] = { d = { vim.diagnostic.goto_prev, "Previous diagnostic" }, }, ["]"] = { d = { vim.diagnostic.goto_next, "Next diagnostic" }, }, }, { buffer = bufnr, silent = true }) if client.server_capabilities.inlayHintProvider then local slow_lsp_servers = { "rust_analyzer", } local timeout = vim.tbl_contains(slow_lsp_servers, client.name, {}) and 500 or 0 vim.defer_fn(function() vim.lsp.inlay_hint.enable(bufnr, true) end, timeout) end end local lspconfig_default_options = { on_attach = on_attach_def, capabilities = capabilities, flags = { debounce_text_changes = 100, }, } ---function to add default options to lspconfig ---@param lsp string ---@param options table ---@return nil local function lspconfig_setup(lsp, options) local final_options = vim.tbl_deep_extend("force", lspconfig_default_options, options) lspconfig[lsp].setup(final_options) end local servers = { "bashls", "gleam", "gopls", "nil_ls", "nixd", "pylsp", "ruff_lsp", "templ", "typst_lsp", } for _, lsp in ipairs(servers) do lspconfig_setup(lsp, {}) end -- Add templ filetype vim.filetype.add({ extension = { templ = "templ" } }) lspconfig_setup("htmx", { filetypes = { "html", "templ" }, }) lspconfig_setup("tailwindcss", { filetypes = { "templ", "astro", "javascript", "typescript", "react" }, init_options = { userLanguages = { templ = "html" } }, }) lspconfig_setup("rust_analyzer", { settings = { ["rust-analyzer"] = { checkOnSave = { command = "clippy", }, }, }, }) lspconfig_setup("lua_ls", { settings = { Lua = { runtime = { -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) version = "LuaJIT", path = vim.split(package.path, ";"), }, diagnostics = { -- Get the language server to recognize the `vim` global globals = { "vim" }, }, workspace = { -- Make the server aware of Neovim runtime files library = vim.api.nvim_get_runtime_file("", true), checkThirdParty = false, }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false, }, format = { enable = false, }, hint = { enable = true, }, }, }, })