From af7dced8b1fe8b2137484d9633c33aad47f7c38d Mon Sep 17 00:00:00 2001 From: Micah Halter Date: Thu, 20 Jul 2023 12:01:55 -0400 Subject: [PATCH] refactor!: move defaults to configuration through setup --- lua/astrolsp/config.lua | 19 +++++ lua/astrolsp/config/init.lua | 96 ------------------------ lua/astrolsp/config/mappings.lua | 122 ------------------------------- lua/astrolsp/init.lua | 67 +++++++---------- lua/astrolsp/toggles.lua | 4 +- 5 files changed, 47 insertions(+), 261 deletions(-) create mode 100644 lua/astrolsp/config.lua delete mode 100644 lua/astrolsp/config/init.lua delete mode 100644 lua/astrolsp/config/mappings.lua diff --git a/lua/astrolsp/config.lua b/lua/astrolsp/config.lua new file mode 100644 index 0000000..42f2900 --- /dev/null +++ b/lua/astrolsp/config.lua @@ -0,0 +1,19 @@ +return { + features = { + autoformat_enabled = true, + codelens = true, + diagnostics_mode = 3, + inlay_hints = false, + lsp_handlers = true, + semantic_tokens = true, + }, + capabilities = {}, + config = {}, + diagnostics = {}, + flags = {}, + formatting = { format_on_save = { enabled = true }, disabled = {} }, + mappings = {}, + servers = {}, + setup_handlers = { function(server, opts) require("lspconfig")[server].setup(opts) end }, + on_attach = nil, +} diff --git a/lua/astrolsp/config/init.lua b/lua/astrolsp/config/init.lua deleted file mode 100644 index ed904fa..0000000 --- a/lua/astrolsp/config/init.lua +++ /dev/null @@ -1,96 +0,0 @@ -local schemastore_avail, schemastore = pcall(require, "schemastore") - -return { - features = { - autoformat_enabled = true, - codelens = true, - diagnostics_mode = 3, - inlay_hints = false, - lsp_handlers = true, - semantic_tokens = true, - }, - - diagnostics = { - virtual_text = true, - signs = { - active = { - { name = "DiagnosticSignError", text = "", texthl = "DiagnosticSignError" }, - { name = "DiagnosticSignHint", text = "󰌵", texthl = "DiagnosticSignHint" }, - { name = "DiagnosticSignInfo", text = "󰋼", texthl = "DiagnosticSignInfo" }, - { name = "DiagnosticSignWarn", text = "", texthl = "DiagnosticSignWarn" }, - { name = "DapBreakpoint", text = "", texthl = "DiagnosticInfo" }, - { name = "DapBreakpointCondition", text = "", texthl = "DiagnosticInfo" }, - { name = "DapBreakpointRejected", text = "", texthl = "DiagnosticError" }, - { name = "DapLogPoint", text = ".>", texthl = "DiagnosticInfo" }, - { name = "DapStopped", text = "󰁕", texthl = "DiagnosticWarn" }, - }, - }, - update_in_insert = true, - underline = true, - severity_sort = true, - float = { - focused = false, - style = "minimal", - border = "rounded", - source = "always", - header = "", - prefix = "", - }, - }, - - capabilities = vim.tbl_deep_extend("force", vim.lsp.protocol.make_client_capabilities(), { - textDocument = { - completion = { - completionItem = { - documentationFormat = { "markdown", "plaintext" }, - snippetSupport = true, - preselectSupport = true, - insertReplaceSupport = true, - labelDetailsSupport = true, - deprecatedSupport = true, - commitCharactersSupport = true, - tagSupport = { valueSet = { 1 } }, - resolveSupport = { properties = { "documentation", "detail", "additionalTextEdits" } }, - }, - }, - foldingRange = { dynamicRegistration = false, lineFoldingOnly = true }, - }, - }), - - flags = {}, - - config = { - jsonls = { - settings = { - json = { - schemas = schemastore_avail and schemastore.json.schemas() or nil, - validate = { enable = schemastore_avail }, - }, - }, - }, - yamlls = { settings = { yaml = { schemas = schemastore_avail and schemastore.json.schemas() or nil } } }, - lua_ls = { - before_init = function(param, config) - if vim.b.neodev_enabled and type(astronvim) == "table" and type(astronvim.supported_configs) == "table" then - for _, astronvim_config in ipairs(astronvim.supported_configs) do - if param.rootPath:match(astronvim_config) then - table.insert(config.settings.Lua.workspace.library, astronvim.install.home .. "/lua") - break - end - end - end - end, - settings = { Lua = { workspace = { checkThirdParty = false } } }, - }, - }, - - servers = {}, - - -- on_attach = function(client, bufnr) ... end, -- user can pass in an extension of the on_attach - - setup_handlers = { function(server, opts) require("lspconfig")[server].setup(opts) end }, - - formatting = { format_on_save = { enabled = true }, disabled = {} }, - - mappings = require "astrolsp.config.mappings", -} diff --git a/lua/astrolsp/config/mappings.lua b/lua/astrolsp/config/mappings.lua deleted file mode 100644 index 71d9024..0000000 --- a/lua/astrolsp/config/mappings.lua +++ /dev/null @@ -1,122 +0,0 @@ -local M = {} - -for _, mode in ipairs { "", "n", "v", "x", "s", "o", "!", "i", "l", "c", "t" } do - M[mode] = {} -end -if vim.fn.has "nvim-0.10.0" == 1 then - for _, abbr_mode in ipairs { "ia", "ca", "!a" } do - M[abbr_mode] = {} - end -end - -M.n["ld"] = { function() vim.diagnostic.open_float() end, desc = "Hover diagnostics" } -M.n["[d"] = { function() vim.diagnostic.goto_prev() end, desc = "Previous diagnostic" } -M.n["]d"] = { function() vim.diagnostic.goto_next() end, desc = "Next diagnostic" } -M.n["gl"] = { function() vim.diagnostic.open_float() end, desc = "Hover diagnostics" } - -M.n["lD"] = { - function() require("telescope.builtin").diagnostics() end, - desc = "Search diagnostics", - cond = function(_, _) return true end, -- client, bufnr parameters -} - -M.n["la"] = { - function() vim.lsp.buf.code_action() end, - desc = "LSP code action", - cond = "testDocument/codeAction", -- LSP client capability string -} -M.v["la"] = M.n["la"] - -M.n["ll"] = - { function() vim.lsp.codelens.refresh() end, desc = "LSP CodeLens refresh", cond = "textDocument/codeLens" } -M.n["lL"] = { function() vim.lsp.codelens.run() end, desc = "LSP CodeLens run", cond = "textDocument/codeLens" } - -M.n["gD"] = { - function() vim.lsp.buf.declaration() end, - desc = "Declaration of current symbol", - cond = "textDocument/declaration", -} -M.n["gd"] = { - function() vim.lsp.buf.definition() end, - desc = "Show the definition of current symbol", - cond = "textDocument/definition", -} - -M.n["lf"] = - { function() vim.lsp.buf.format(M.format_opts) end, desc = "Format buffer", cond = "textDocument/formatting" } -M.v["lf"] = M.n["lf"] -M.n["uf"] = { - function() require("astrolsp.toggles").buffer_autoformat() end, - desc = "Toggle autoformatting (buffer)", - cond = "textDocument/formatting", -} -M.n["uF"] = { - function() require("astrolsp.toggles").autoformat() end, - desc = "Toggle autoformatting (global)", - cond = "textDocument/formatting", -} - -M.n["K"] = { function() vim.lsp.buf.hover() end, desc = "Hover symbol details", cond = "textDocument/hover" } - -M.n["gI"] = { - function() vim.lsp.buf.implementation() end, - desc = "Implementation of current symbol", - cond = "textDocument/implementation", -} - -M.n["uH"] = { - function() require("astrolsp.toggles").buffer_inlay_hints() end, - desc = "Toggle LSP inlay hints (buffer)", - cond = vim.lsp.inlay_hint and "textDocument/inlayHint" or false, -} - -M.n["gr"] = - { function() vim.lsp.buf.references() end, desc = "References of current symbol", cond = "textDocument/references" } -M.n["lR"] = - { function() vim.lsp.buf.references() end, desc = "Search references", cond = "textDocument/references" } - -M.n["lr"] = - { function() vim.lsp.buf.rename() end, desc = "Rename current symbol", cond = "textDocument/rename" } - -M.n["lh"] = - { function() vim.lsp.buf.signature_help() end, desc = "Signature help", cond = "textDocument/signatureHelp" } - -M.n["gT"] = { - function() vim.lsp.buf.type_definition() end, - desc = "Definition of current type", - cond = "textDocument/typeDefinition", -} - -M.n["lG"] = - { function() vim.lsp.buf.workspace_symbol() end, desc = "Search workspace symbols", cond = "workspace/symbol" } - -M.n["uY"] = { - function() require("astrolsp.toggles").buffer_semantic_tokens() end, - desc = "Toggle LSP semantic highlight (buffer)", - cond = "textDocument/semanticTokens/full", -} - --- TODO: FIX this --- if not vim.tbl_isempty(M.v) then M.v["l"] = { desc = " LSP" } end - -if vim.fn.exists ":LspInfo" > 0 then M.n["li"] = { "LspInfo", desc = "LSP information" } end --- -if vim.fn.exists ":NullLsInfo" > 0 then M.n["lI"] = { "NullLsInfo", desc = "Null-ls information" } end - -if vim.fn.exists ":Telescope" > 0 or pcall(require, "telescope") then -- setup telescope mappings if available - M.n["lD"] = { function() require("telescope.builtin").diagnostics() end, desc = "Search diagnostics" } - if M.n.gd then M.n.gd[1] = function() require("telescope.builtin").lsp_definitions() end end - if M.n.gI then M.n.gI[1] = function() require("telescope.builtin").lsp_implementations() end end - if M.n.gr then M.n.gr[1] = function() require("telescope.builtin").lsp_references() end end - if M.n["lR"] then M.n["lR"][1] = function() require("telescope.builtin").lsp_references() end end - if M.n.gT then M.n.gT[1] = function() require("telescope.builtin").lsp_type_definitions() end end - if M.n["lG"] then - M.n["lG"][1] = function() - vim.ui.input({ prompt = "Symbol Query: " }, function(query) - if query then require("telescope.builtin").lsp_workspace_symbols { query = query } end - end) - end - end -end - -return M diff --git a/lua/astrolsp/init.lua b/lua/astrolsp/init.lua index f84e502..cb9c38c 100644 --- a/lua/astrolsp/init.lua +++ b/lua/astrolsp/init.lua @@ -3,6 +3,7 @@ local M = {} local tbl_contains = vim.tbl_contains local tbl_isempty = vim.tbl_isempty +M.config = require "astrolsp.config" M.lsp_progress = {} local function event(name) @@ -10,32 +11,16 @@ local function event(name) end function M.setup(opts) - opts = opts or {} - for section, default in pairs(require "astrolsp.config") do - local opt = opts[section] - if opt then - if type(opt) == "function" then - opts[section] = opt(default) or default - elseif type(opt) == "table" then - opts[section] = vim.tbl_deep_extend("force", default, opt) - else - vim.api.nvim_err_writeln(("AstroLSP: Invalid %s option"):format(section)) - end - else - opts[section] = default - end - end - - M.options = opts + M.config = vim.tbl_deep_extend("force", M.config, opts) M.setup_diagnostics() - M.format_opts = vim.deepcopy(M.options.formatting) + M.format_opts = vim.deepcopy(M.config.formatting) M.format_opts.disabled = nil M.format_opts.format_on_save = nil M.format_opts.filter = function(client) - local filter = M.options.formatting.filter - local disabled = M.options.formatting.disabled or {} + local filter = M.config.formatting.filter + local disabled = M.config.formatting.disabled or {} -- check if client is fully disabled or filtered by function return not (vim.tbl_contains(disabled, client.name) or (type(filter) == "function" and not filter(client))) end @@ -54,7 +39,7 @@ function M.setup(opts) orig_handler(_, msg, info) end - if M.options.features.lsp_handlers then + if M.config.features.lsp_handlers then vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "rounded", silent = true }) vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = "rounded", silent = true }) @@ -64,25 +49,25 @@ end M.diagnostics = { [0] = {}, {}, {}, {} } function M.setup_diagnostics() - for _, sign in ipairs(M.options.diagnostics.signs.active) do + for _, sign in ipairs(M.config.diagnostics.signs.active) do vim.fn.sign_define(sign.name, sign) end M.diagnostics = { -- diagnostics off [0] = vim.tbl_deep_extend( "force", - M.options.diagnostics, + M.config.diagnostics, { underline = false, virtual_text = false, signs = false, update_in_insert = false } ), -- status only - vim.tbl_deep_extend("force", M.options.diagnostics, { virtual_text = false, signs = false }), + vim.tbl_deep_extend("force", M.config.diagnostics, { virtual_text = false, signs = false }), -- virtual text off, signs on - vim.tbl_deep_extend("force", M.options.diagnostics, { virtual_text = false }), + vim.tbl_deep_extend("force", M.config.diagnostics, { virtual_text = false }), -- all diagnostics on - M.options.diagnostics, + M.config.diagnostics, } - vim.diagnostic.config(M.diagnostics[M.options.features.diagnostics_mode]) + vim.diagnostic.config(M.diagnostics[M.config.features.diagnostics_mode]) end --- Helper function to set up a given server with the Neovim LSP client @@ -95,11 +80,11 @@ function M.lsp_setup(server) -- if server doesn't exist, set it up from user server definition local config_avail, config = pcall(require, "lspconfig.server_configurations." .. server) if not config_avail or not config.default_config then - local server_definition = M.options.config[server] + local server_definition = M.config.config[server] if server_definition.cmd then require("lspconfig.configs")[server] = { default_config = server_definition } end end - local opts = M.config(server) - local setup_handler = M.options.setup_handlers[server] or M.options.setup_handlers[1] + local opts = M.lsp_opts(server) + local setup_handler = M.config.setup_handlers[server] or M.config.setup_handlers[1] if setup_handler then setup_handler(server, opts) end end @@ -143,14 +128,14 @@ M.on_attach = function(client, bufnr) del_buffer_autocmd("lsp_codelens_refresh", bufnr) return end - if M.options.features.codelens then vim.lsp.codelens.refresh() end + if M.config.features.codelens then vim.lsp.codelens.refresh() end end, }) - if M.options.features.codelens then vim.lsp.codelens.refresh() end + if M.config.features.codelens then vim.lsp.codelens.refresh() end end if - client.supports_method "textDocument/formatting" and not tbl_contains(M.options.formatting.disabled, client.name) + client.supports_method "textDocument/formatting" and not tbl_contains(M.config.formatting.disabled, client.name) then vim.api.nvim_buf_create_user_command( bufnr, @@ -158,7 +143,7 @@ M.on_attach = function(client, bufnr) function() vim.lsp.buf.format(M.format_opts) end, { desc = "Format file with LSP" } ) - local autoformat = M.options.formatting.format_on_save + local autoformat = M.config.formatting.format_on_save local filetype = vim.api.nvim_get_option_value("filetype", { buf = bufnr }) if vim.b[bufnr].autoformat_enabled == nil then vim.b[bufnr].autoformat_enabled = autoformat.enabled @@ -204,17 +189,17 @@ M.on_attach = function(client, bufnr) end if client.supports_method "textDocument/inlayHint" then - if vim.b[bufnr].inlay_hints == nil then vim.b[bufnr].inlay_hints = M.options.features.inlay_hints end + if vim.b[bufnr].inlay_hints == nil then vim.b[bufnr].inlay_hints = M.config.features.inlay_hints end -- TODO: remove check after dropping support for Neovim v0.9 if vim.lsp.inlay_hint and vim.b[bufnr].inlay_hints then vim.lsp.inlay_hint(bufnr, true) end end if client.supports_method and vim.lsp.semantic_tokens then - if vim.b[bufnr].semantic_tokens == nil then vim.b[bufnr].semantic_tokens = M.options.features.semantic_tokens end + if vim.b[bufnr].semantic_tokens == nil then vim.b[bufnr].semantic_tokens = M.config.features.semantic_tokens end if not vim.b[bufnr].semantic_tokens then vim.lsp.semantic_tokens["stop"](bufnr, client.id) end end - for mode, maps in pairs(M.options.mappings) do + for mode, maps in pairs(M.config.mappings) do for lhs, map_opts in pairs(maps) do if map_opts.cond == nil @@ -236,25 +221,25 @@ M.on_attach = function(client, bufnr) end end - if type(M.options.on_attach) == "function" then M.options.on_attach(client, bufnr) end + if type(M.config.on_attach) == "function" then M.config.on_attach(client, bufnr) end end --- Get the server configuration for a given language server to be provided to the server's `setup()` call ---@param server_name string The name of the server ---@return table # The table of LSP options used when setting up the given language server -function M.config(server_name) +function M.lsp_opts(server_name) if server_name == "lua_ls" then pcall(require, "neodev") end local server = require("lspconfig")[server_name] local opts = vim.tbl_deep_extend( "force", vim.tbl_deep_extend("force", server.document_config.default_config, server), - { capabilities = M.options.capabilities, flags = M.options.flags } + { capabilities = M.config.capabilities, flags = M.config.flags } ) -- HACK: add astronvim interoperability, remove after AstroNvim v4 if type(astronvim) == "table" and type(astronvim.user_opts) == "function" then opts = astronvim.user_opts("lsp.config." .. server_name, opts) end - if M.options.config[server_name] then opts = vim.tbl_deep_extend("force", opts, M.options.config[server_name]) end + if M.config.config[server_name] then opts = vim.tbl_deep_extend("force", opts, M.config.config[server_name]) end assert(opts) local old_on_attach = require("lspconfig")[server_name].on_attach diff --git a/lua/astrolsp/toggles.lua b/lua/astrolsp/toggles.lua index 40acf08..19c0098 100644 --- a/lua/astrolsp/toggles.lua +++ b/lua/astrolsp/toggles.lua @@ -1,7 +1,7 @@ local M = {} -local options = require("astrolsp").options -local features = options.features +local config = require("astrolsp").config +local features = config.features local notify = vim.notify local function bool2str(bool) return bool and "on" or "off" end