]> git.rmz.io Git - dotfiles.git/blobdiff - nvim/lua/plugins/lsp/init.lua
lazyvim: absorb lspconfig
[dotfiles.git] / nvim / lua / plugins / lsp / init.lua
diff --git a/nvim/lua/plugins/lsp/init.lua b/nvim/lua/plugins/lsp/init.lua
new file mode 100644 (file)
index 0000000..351f060
--- /dev/null
@@ -0,0 +1,176 @@
+return {
+  { "neovim/nvim-lspconfig",
+    event = "LazyFile",
+    dependencies = {
+      "mason.nvim",
+      { "williamboman/mason-lspconfig.nvim", config = function() end }, -- don't configure yet
+    },
+    ---@class PluginLspOpts
+    opts = {
+      ---@type vim.diagnostic.Opts
+      diagnostics = {
+        underline = true,
+        update_in_insert = false,
+        virtual_text = {
+          spacing = 4,
+          source = "if_many",
+          prefix = "●",
+        },
+        severity_sort = true,
+        signs = {
+          text = {
+            [vim.diagnostic.severity.ERROR] = " ",
+            [vim.diagnostic.severity.WARN]  = " ",
+            [vim.diagnostic.severity.HINT]  = " ",
+            [vim.diagnostic.severity.INFO]  = " ",
+          },
+        },
+      },
+      inlay_hints = { enabled = false, },
+      codelens = { enabled = false, },
+      document_highlight = { enabled = true, },
+      capabilities = {
+        workspace = {
+          fileOperations = {
+            didRename = true,
+            willRename = true,
+          },
+        },
+      },
+      format = {
+        formatting_options = nil,
+        timeout_ms = nil,
+      },
+      -- LSP Server Settings
+      ---@type lspconfig.options
+      servers = {
+        lua_ls = {
+          settings = {
+            Lua = {
+              workspace = { checkThirdParty = false, },
+              codeLens = { enable = true, },
+              completion = { callSnippet = "Replace", },
+              doc = { privateName = { "^_" }, },
+              hint = {
+                enable = true,
+                setType = false,
+                paramType = true,
+                paramName = "Disable",
+                semicolon = "Disable",
+                arrayIndex = "Disable",
+              },
+              diagnostics = {
+                disable = { "missing-fields", },
+              },
+            },
+          },
+        },
+        -- TODO: Add clangd extensions
+        -- https://github.com/p00f/clangd_extensions.nvim
+      },
+      -- you can do any additional lsp server setup here
+      -- return true if you don't want this server to be setup with lspconfig
+      ---@type table<string, fun(server:string, opts:_.lspconfig.options):boolean?>
+      setup = {
+        -- example to setup with typescript.nvim
+        -- tsserver = function(_, opts)
+        --   require("typescript").setup({ server = opts })
+        --   return true
+        -- end,
+        -- Specify * to use this function as a fallback for any server
+        -- ["*"] = function(server, opts) end,
+      },
+    },
+    ---@param opts PluginLspOpts
+    config = function(_, opts)
+      local lspconfig = require('lspconfig')
+      for server, config in pairs(opts.servers) do
+        local capabilities = vim.tbl_deep_extend("force",
+          vim.lsp.protocol.make_client_capabilities() or {},
+          require('blink.cmp').get_lsp_capabilities() or {},
+          config.capabilities or {}
+        )
+        config.capabilities = capabilities
+        lspconfig[server].setup(config)
+      end
+
+      -- setup keymaps
+      LazyVim.lsp.on_attach(function(client, buffer)
+        require("plugins.lsp.keymaps").on_attach(client, buffer)
+      end)
+
+      LazyVim.lsp.setup()
+      LazyVim.lsp.on_dynamic_capability(require("plugins.lsp.keymaps").on_attach)
+      -- TODO: should vim.diagnostics be condigured directly?
+      vim.diagnostic.config(vim.deepcopy(opts.diagnostics))
+
+      -- get all the servers that are available through mason-lspconfig
+      local have_mason, mlsp = pcall(require, "mason-lspconfig")
+      local all_mslp_servers = {}
+      if have_mason then
+        all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package)
+      end
+
+      local ensure_installed = {} ---@type string[]
+      for server, server_opts in pairs(opts.servers) do
+        if server_opts then
+          server_opts = server_opts == true and {} or server_opts
+          if server_opts.enabled ~= false then
+            -- run manual setup if mason=false or if this is a server that cannot be installed with mason-lspconfig
+            if server_opts.mason == false or not vim.tbl_contains(all_mslp_servers, server) then
+              require("lspconfig")[server].setup(server_opts)
+            else
+              ensure_installed[#ensure_installed + 1] = server
+            end
+          end
+        end
+      end
+
+      if have_mason then
+        mlsp.setup({
+          ensure_installed = vim.tbl_deep_extend(
+            "force",
+            ensure_installed,
+            LazyVim.opts("mason-lspconfig.nvim").ensure_installed or {}
+          ),
+          handlers = { setup },
+        })
+      end
+    end
+  },
+  { "williamboman/mason.nvim",
+    cmd = "Mason",
+    keys = { { "<leader>cm", "<cmd>Mason<cr>", desc = "Mason" } },
+    build = ":MasonUpdate",
+    opts_extend = { "ensure_installed" },
+    opts = {
+      ensure_installed = {
+        "stylua",
+        "shfmt",
+      },
+    },
+    ---@param opts MasonSettings | {ensure_installed: string[]}
+    config = function(_, opts)
+      require("mason").setup(opts)
+      local mr = require("mason-registry")
+      mr:on("package:install:success", function()
+        vim.defer_fn(function()
+          -- trigger FileType event to possibly load this newly installed LSP server
+          require("lazy.core.handler.event").trigger({
+            event = "FileType",
+            buf = vim.api.nvim_get_current_buf(),
+          })
+        end, 100)
+      end)
+
+      mr.refresh(function()
+        for _, tool in ipairs(opts.ensure_installed) do
+          local p = mr.get_package(tool)
+          if not p:is_installed() then
+            p:install()
+          end
+        end
+      end)
+    end,
+  },
+}