summaryrefslogtreecommitdiff
path: root/mac/.config/LunarVim/lua/lvim/lsp
diff options
context:
space:
mode:
Diffstat (limited to 'mac/.config/LunarVim/lua/lvim/lsp')
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/config.lua164
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/init.lua128
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/manager.lua141
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/null-ls/code_actions.lua26
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/null-ls/formatters.lua33
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/null-ls/init.lua16
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/null-ls/linters.lua43
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/null-ls/services.lua104
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/providers/jsonls.lua18
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/providers/lua_ls.lua64
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/providers/tailwindcss.lua15
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/providers/vuels.lua26
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/providers/yamlls.lua16
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/templates.lua76
-rw-r--r--mac/.config/LunarVim/lua/lvim/lsp/utils.lua185
15 files changed, 1055 insertions, 0 deletions
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/config.lua b/mac/.config/LunarVim/lua/lvim/lsp/config.lua
new file mode 100644
index 0000000..55f7d64
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/config.lua
@@ -0,0 +1,164 @@
+local skipped_servers = {
+ "angularls",
+ "ansiblels",
+ "antlersls",
+ "ast_grep",
+ "azure_pipelines_ls",
+ "basedpyright",
+ "biome",
+ "bzl",
+ "ccls",
+ "css_variables",
+ "cssmodules_ls",
+ "custom_elements_ls",
+ "denols",
+ "docker_compose_language_service",
+ "dprint",
+ "elp",
+ "ember",
+ "emmet_language_server",
+ "emmet_ls",
+ "eslint",
+ "eslintls",
+ "fennel_language_server",
+ "gitlab_ci_ls",
+ "glint",
+ "glslls",
+ "golangci_lint_ls",
+ "gradle_ls",
+ "graphql",
+ "harper_ls",
+ "hdl_checker",
+ "hydra_lsp",
+ "htmx",
+ "java_language_server",
+ "jedi_language_server",
+ "lexical",
+ "ltex",
+ "lwc_ls",
+ "mdx_analyzer",
+ "neocmake",
+ "nim_langserver",
+ "ocamlls",
+ "omnisharp",
+ "phpactor",
+ "psalm",
+ "pylsp",
+ "pylyzer",
+ "pyre",
+ "quick_lint_js",
+ "reason_ls",
+ "rnix",
+ "rome",
+ "rubocop",
+ "ruby_ls",
+ "ruby_lsp",
+ "ruff_lsp",
+ "scry",
+ "snyk_ls",
+ "solang",
+ "solc",
+ "solidity_ls",
+ "solidity_ls_nomicfoundation",
+ "sorbet",
+ "sourcekit",
+ "somesass_ls",
+ "sourcery",
+ "spectral",
+ "sqlls",
+ "sqls",
+ "standardrb",
+ "stimulus_ls",
+ "stylelint_lsp",
+ "svlangserver",
+ "swift_mesonls",
+ "templ",
+ "tflint",
+ "tinymist",
+ "unocss",
+ "vale_ls",
+ "vacuum",
+ "verible",
+ "v_analyzer",
+ "vtsls",
+ "vuels",
+}
+
+local skipped_filetypes = { "markdown", "rst", "plaintext", "toml", "proto" }
+
+local join_paths = require("lvim.utils").join_paths
+
+return {
+ templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"),
+ ---@deprecated use vim.diagnostic.config({ ... }) instead
+ diagnostics = {},
+ document_highlight = false,
+ code_lens_refresh = true,
+ on_attach_callback = nil,
+ on_init_callback = nil,
+ automatic_configuration = {
+ ---@usage list of servers that the automatic installer will skip
+ skipped_servers = skipped_servers,
+ ---@usage list of filetypes that the automatic installer will skip
+ skipped_filetypes = skipped_filetypes,
+ },
+ buffer_mappings = {
+ normal_mode = {
+ ["K"] = { "<cmd>lua vim.lsp.buf.hover()<cr>", "Show hover" },
+ ["gd"] = { "<cmd>lua vim.lsp.buf.definition()<cr>", "Goto definition" },
+ ["gD"] = { "<cmd>lua vim.lsp.buf.declaration()<cr>", "Goto Declaration" },
+ ["gr"] = { "<cmd>lua vim.lsp.buf.references()<cr>", "Goto references" },
+ ["gI"] = { "<cmd>lua vim.lsp.buf.implementation()<cr>", "Goto Implementation" },
+ ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<cr>", "show signature help" },
+ ["gl"] = {
+ function()
+ local float = vim.diagnostic.config().float
+
+ if float then
+ local config = type(float) == "table" and float or {}
+ config.scope = "line"
+
+ vim.diagnostic.open_float(config)
+ end
+ end,
+ "Show line diagnostics",
+ },
+ },
+ insert_mode = {},
+ visual_mode = {},
+ },
+ buffer_options = {
+ --- enable completion triggered by <c-x><c-o>
+ omnifunc = "v:lua.vim.lsp.omnifunc",
+ --- use gq for formatting
+ formatexpr = "v:lua.vim.lsp.formatexpr(#{timeout_ms:500})",
+ },
+ ---@usage list of settings of nvim-lsp-installer
+ installer = {
+ setup = {
+ ensure_installed = {},
+ automatic_installation = {
+ exclude = {},
+ },
+ },
+ },
+ nlsp_settings = {
+ setup = {
+ config_home = join_paths(get_config_dir(), "lsp-settings"),
+ -- set to false to overwrite schemastore.nvim
+ append_default_schemas = true,
+ ignored_servers = {},
+ loader = "json",
+ },
+ },
+ null_ls = {
+ setup = {
+ debug = false,
+ },
+ config = {},
+ },
+ ---@deprecated use lvim.lsp.automatic_configuration.skipped_servers instead
+ override = {},
+ ---@deprecated use lvim.lsp.installer.setup.automatic_installation instead
+ automatic_servers_installation = nil,
+}
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/init.lua b/mac/.config/LunarVim/lua/lvim/lsp/init.lua
new file mode 100644
index 0000000..d59b29a
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/init.lua
@@ -0,0 +1,128 @@
+local M = {}
+local Log = require "lvim.core.log"
+local utils = require "lvim.utils"
+local autocmds = require "lvim.core.autocmds"
+
+local function add_lsp_buffer_options(bufnr)
+ for k, v in pairs(lvim.lsp.buffer_options) do
+ vim.api.nvim_set_option_value(k, v, { buf = bufnr })
+ end
+end
+
+local function add_lsp_buffer_keybindings(bufnr)
+ local mappings = {
+ normal_mode = "n",
+ insert_mode = "i",
+ visual_mode = "v",
+ }
+
+ for mode_name, mode_char in pairs(mappings) do
+ for key, remap in pairs(lvim.lsp.buffer_mappings[mode_name]) do
+ local opts = { buffer = bufnr, desc = remap[2], noremap = true, silent = true }
+ vim.keymap.set(mode_char, key, remap[1], opts)
+ end
+ end
+end
+
+function M.common_capabilities()
+ local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
+ if status_ok then
+ return cmp_nvim_lsp.default_capabilities()
+ end
+
+ local capabilities = vim.lsp.protocol.make_client_capabilities()
+ capabilities.textDocument.completion.completionItem.snippetSupport = true
+ capabilities.textDocument.completion.completionItem.resolveSupport = {
+ properties = {
+ "documentation",
+ "detail",
+ "additionalTextEdits",
+ },
+ }
+
+ return capabilities
+end
+
+function M.common_on_exit(_, _)
+ if lvim.lsp.document_highlight then
+ autocmds.clear_augroup "lsp_document_highlight"
+ end
+ if lvim.lsp.code_lens_refresh then
+ autocmds.clear_augroup "lsp_code_lens_refresh"
+ end
+end
+
+function M.common_on_init(client, bufnr)
+ if lvim.lsp.on_init_callback then
+ lvim.lsp.on_init_callback(client, bufnr)
+ Log:debug "Called lsp.on_init_callback"
+ return
+ end
+end
+
+function M.common_on_attach(client, bufnr)
+ if lvim.lsp.on_attach_callback then
+ lvim.lsp.on_attach_callback(client, bufnr)
+ Log:debug "Called lsp.on_attach_callback"
+ end
+ local lu = require "lvim.lsp.utils"
+ if lvim.lsp.document_highlight then
+ lu.setup_document_highlight(client, bufnr)
+ end
+ if lvim.lsp.code_lens_refresh then
+ lu.setup_codelens_refresh(client, bufnr)
+ end
+ add_lsp_buffer_keybindings(bufnr)
+ add_lsp_buffer_options(bufnr)
+ lu.setup_document_symbols(client, bufnr)
+end
+
+function M.get_common_opts()
+ return {
+ on_attach = M.common_on_attach,
+ on_init = M.common_on_init,
+ on_exit = M.common_on_exit,
+ capabilities = M.common_capabilities(),
+ }
+end
+
+function M.setup()
+ Log:debug "Setting up LSP support"
+
+ local lsp_status_ok, _ = pcall(require, "lspconfig")
+ if not lsp_status_ok then
+ return
+ end
+
+ if lvim.use_icons then
+ for _, sign in ipairs(vim.tbl_get(vim.diagnostic.config(), "signs", "values") or {}) do
+ vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
+ end
+ end
+
+ if not utils.is_directory(lvim.lsp.templates_dir) then
+ require("lvim.lsp.templates").generate_templates()
+ end
+
+ pcall(function()
+ require("nlspsettings").setup(lvim.lsp.nlsp_settings.setup)
+ end)
+
+ require("lvim.lsp.null-ls").setup()
+
+ autocmds.configure_format_on_save()
+
+ local function set_handler_opts_if_not_set(name, handler, opts)
+ if debug.getinfo(vim.lsp.handlers[name], "S").source:find(vim.env.VIMRUNTIME, 1, true) then
+ vim.lsp.handlers[name] = vim.lsp.with(handler, opts)
+ end
+ end
+
+ set_handler_opts_if_not_set("textDocument/hover", vim.lsp.handlers.hover, { border = "rounded" })
+ set_handler_opts_if_not_set("textDocument/signatureHelp", vim.lsp.handlers.signature_help, { border = "rounded" })
+
+ -- Enable rounded borders in :LspInfo window.
+ require("lspconfig.ui.windows").default_options.border = "rounded"
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/manager.lua b/mac/.config/LunarVim/lua/lvim/lsp/manager.lua
new file mode 100644
index 0000000..5e695ec
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/manager.lua
@@ -0,0 +1,141 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+local fmt = string.format
+local lvim_lsp_utils = require "lvim.lsp.utils"
+local is_windows = vim.loop.os_uname().version:match "Windows"
+
+local function resolve_mason_config(server_name)
+ local found, mason_config = pcall(require, "mason-lspconfig.server_configurations." .. server_name)
+ if not found then
+ Log:debug(fmt("mason configuration not found for %s", server_name))
+ return {}
+ end
+ local server_mapping = require "mason-lspconfig.mappings.server"
+ local path = require "mason-core.path"
+ local pkg_name = server_mapping.lspconfig_to_package[server_name]
+ local install_dir = path.package_prefix(pkg_name)
+ local conf = mason_config(install_dir)
+ if is_windows and conf.cmd and conf.cmd[1] then
+ local exepath = vim.fn.exepath(conf.cmd[1])
+ if exepath ~= "" then
+ conf.cmd[1] = exepath
+ end
+ end
+ Log:debug(fmt("resolved mason configuration for %s, got %s", server_name, vim.inspect(conf)))
+ return conf or {}
+end
+
+---Resolve the configuration for a server by merging with the default config
+---@param server_name string
+---@vararg any config table [optional]
+---@return table
+local function resolve_config(server_name, ...)
+ local defaults = {
+ on_attach = require("lvim.lsp").common_on_attach,
+ on_init = require("lvim.lsp").common_on_init,
+ on_exit = require("lvim.lsp").common_on_exit,
+ capabilities = require("lvim.lsp").common_capabilities(),
+ }
+
+ local has_custom_provider, custom_config = pcall(require, "lvim/lsp/providers/" .. server_name)
+ if has_custom_provider then
+ Log:debug("Using custom configuration for requested server: " .. server_name)
+ defaults = vim.tbl_deep_extend("force", defaults, custom_config)
+ end
+
+ defaults = vim.tbl_deep_extend("force", defaults, ...)
+
+ return defaults
+end
+
+-- manually start the server and don't wait for the usual filetype trigger from lspconfig
+local function buf_try_add(server_name, bufnr)
+ bufnr = bufnr or vim.api.nvim_get_current_buf()
+ require("lspconfig")[server_name].manager:try_add_wrapper(bufnr)
+end
+
+-- check if the manager autocomd has already been configured since some servers can take a while to initialize
+-- this helps guarding against a data-race condition where a server can get configured twice
+-- which seems to occur only when attaching to single-files
+local function client_is_configured(server_name, ft)
+ ft = ft or vim.bo.filetype
+ local active_autocmds = vim.api.nvim_get_autocmds { event = "FileType", pattern = ft }
+ for _, result in ipairs(active_autocmds) do
+ if result.desc ~= nil and result.desc:match("server " .. server_name .. " ") then
+ Log:debug(string.format("[%q] is already configured", server_name))
+ return true
+ end
+ end
+ return false
+end
+
+local function launch_server(server_name, config)
+ pcall(function()
+ local command = config.cmd
+ or (function()
+ local default_config = require("lspconfig.server_configurations." .. server_name).default_config
+ return default_config.cmd
+ end)()
+ -- some servers have dynamic commands defined with on_new_config
+ if type(command) == "table" and type(command[1]) == "string" and vim.fn.executable(command[1]) ~= 1 then
+ Log:debug(string.format("[%q] is either not installed, missing from PATH, or not executable.", server_name))
+ return
+ end
+ require("lspconfig")[server_name].setup(config)
+ buf_try_add(server_name)
+ end)
+end
+
+---Setup a language server by providing a name
+---@param server_name string name of the language server
+---@param user_config table? when available it will take predence over any default configurations
+function M.setup(server_name, user_config)
+ vim.validate { name = { server_name, "string" } }
+ user_config = user_config or {}
+
+ if lvim_lsp_utils.is_client_active(server_name) or client_is_configured(server_name) then
+ return
+ end
+
+ local server_mapping = require "mason-lspconfig.mappings.server"
+ local registry = require "mason-registry"
+
+ local pkg_name = server_mapping.lspconfig_to_package[server_name]
+ if not pkg_name then
+ local config = resolve_config(server_name, user_config)
+ launch_server(server_name, config)
+ return
+ end
+
+ local should_auto_install = function(name)
+ local installer_settings = lvim.lsp.installer.setup
+ return installer_settings.automatic_installation
+ and not vim.tbl_contains(installer_settings.automatic_installation.exclude, name)
+ end
+
+ if not registry.is_installed(pkg_name) then
+ if should_auto_install(server_name) then
+ Log:debug "Automatic server installation detected"
+ vim.notify_once(string.format("Installation in progress for [%s]", server_name), vim.log.levels.INFO)
+ local pkg = registry.get_package(pkg_name)
+ pkg:install():once("closed", function()
+ if pkg:is_installed() then
+ vim.schedule(function()
+ vim.notify_once(string.format("Installation complete for [%s]", server_name), vim.log.levels.INFO)
+ -- mason config is only available once the server has been installed
+ local config = resolve_config(server_name, resolve_mason_config(server_name), user_config)
+ launch_server(server_name, config)
+ end)
+ end
+ end)
+ else
+ Log:debug(server_name .. " is not managed by the automatic installer")
+ end
+ end
+
+ local config = resolve_config(server_name, resolve_mason_config(server_name), user_config)
+ launch_server(server_name, config)
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/null-ls/code_actions.lua b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/code_actions.lua
new file mode 100644
index 0000000..50f4cfb
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/code_actions.lua
@@ -0,0 +1,26 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+
+local null_ls = require "null-ls"
+local services = require "lvim.lsp.null-ls.services"
+local method = null_ls.methods.CODE_ACTION
+
+function M.list_registered(filetype)
+ local registered_providers = services.list_registered_providers_names(filetype)
+ return registered_providers[method] or {}
+end
+
+function M.setup(actions_configs)
+ if vim.tbl_isempty(actions_configs) then
+ return
+ end
+
+ local registered = services.register_sources(actions_configs, method)
+
+ if #registered > 0 then
+ Log:debug("Registered the following action-handlers: " .. unpack(registered))
+ end
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/null-ls/formatters.lua b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/formatters.lua
new file mode 100644
index 0000000..b4fb2f3
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/formatters.lua
@@ -0,0 +1,33 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+
+local null_ls = require "null-ls"
+local services = require "lvim.lsp.null-ls.services"
+local method = null_ls.methods.FORMATTING
+
+function M.list_registered(filetype)
+ local registered_providers = services.list_registered_providers_names(filetype)
+ return registered_providers[method] or {}
+end
+
+function M.list_supported(filetype)
+ local s = require "null-ls.sources"
+ local supported_formatters = s.get_supported(filetype, "formatting")
+ table.sort(supported_formatters)
+ return supported_formatters
+end
+
+function M.setup(formatter_configs)
+ if vim.tbl_isempty(formatter_configs) then
+ return
+ end
+
+ local registered = services.register_sources(formatter_configs, method)
+
+ if #registered > 0 then
+ Log:debug("Registered the following formatters: " .. unpack(registered))
+ end
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/null-ls/init.lua b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/init.lua
new file mode 100644
index 0000000..51a200f
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/init.lua
@@ -0,0 +1,16 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+
+function M.setup()
+ local status_ok, null_ls = pcall(require, "null-ls")
+ if not status_ok then
+ Log:error "Missing null-ls dependency"
+ return
+ end
+
+ local default_opts = require("lvim.lsp").get_common_opts()
+ null_ls.setup(vim.tbl_deep_extend("force", default_opts, lvim.lsp.null_ls.setup))
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/null-ls/linters.lua b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/linters.lua
new file mode 100644
index 0000000..ba7670d
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/linters.lua
@@ -0,0 +1,43 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+
+local null_ls = require "null-ls"
+local services = require "lvim.lsp.null-ls.services"
+local method = null_ls.methods.DIAGNOSTICS
+
+local alternative_methods = {
+ null_ls.methods.DIAGNOSTICS,
+ null_ls.methods.DIAGNOSTICS_ON_OPEN,
+ null_ls.methods.DIAGNOSTICS_ON_SAVE,
+}
+
+function M.list_registered(filetype)
+ local registered_providers = services.list_registered_providers_names(filetype)
+ local providers_for_methods = vim.tbl_flatten(vim.tbl_map(function(m)
+ return registered_providers[m] or {}
+ end, alternative_methods))
+
+ return providers_for_methods
+end
+
+function M.list_supported(filetype)
+ local s = require "null-ls.sources"
+ local supported_linters = s.get_supported(filetype, "diagnostics")
+ table.sort(supported_linters)
+ return supported_linters
+end
+
+function M.setup(linter_configs)
+ if vim.tbl_isempty(linter_configs) then
+ return
+ end
+
+ local registered = services.register_sources(linter_configs, method)
+
+ if #registered > 0 then
+ Log:debug("Registered the following linters: " .. unpack(registered))
+ end
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/null-ls/services.lua b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/services.lua
new file mode 100644
index 0000000..7dc0bb6
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/null-ls/services.lua
@@ -0,0 +1,104 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+
+local function find_root_dir()
+ local util = require "lspconfig/util"
+ local lsp_utils = require "lvim.lsp.utils"
+
+ local ts_client = lsp_utils.is_client_active "typescript"
+ if ts_client then
+ return ts_client.config.root_dir
+ end
+ local dirname = vim.fn.expand "%:p:h"
+ return util.root_pattern "package.json"(dirname)
+end
+
+local function from_node_modules(command)
+ local root_dir = find_root_dir()
+
+ if not root_dir then
+ return nil
+ end
+
+ local join_paths = require("lvim.utils").join_paths
+ return join_paths(root_dir, "node_modules", ".bin", command)
+end
+
+local local_providers = {
+ prettier = { find = from_node_modules },
+ prettierd = { find = from_node_modules },
+ prettier_d_slim = { find = from_node_modules },
+ eslint_d = { find = from_node_modules },
+ eslint = { find = from_node_modules },
+ stylelint = { find = from_node_modules },
+}
+
+function M.find_command(command)
+ if local_providers[command] then
+ local local_command = local_providers[command].find(command)
+ if local_command and vim.fn.executable(local_command) == 1 then
+ return local_command
+ end
+ end
+
+ if command and vim.fn.executable(command) == 1 then
+ return command
+ end
+ return nil
+end
+
+function M.list_registered_providers_names(filetype)
+ local s = require "null-ls.sources"
+ local available_sources = s.get_available(filetype)
+ local registered = {}
+ for _, source in ipairs(available_sources) do
+ for method in pairs(source.methods) do
+ registered[method] = registered[method] or {}
+ table.insert(registered[method], source.name)
+ end
+ end
+ return registered
+end
+
+function M.register_sources(configs, method)
+ local null_ls = require "null-ls"
+ local is_registered = require("null-ls.sources").is_registered
+
+ local sources, registered_names = {}, {}
+
+ for _, config in ipairs(configs) do
+ local cmd = config.exe or config.command
+ local name = config.name or cmd:gsub("-", "_")
+ local type = method == null_ls.methods.CODE_ACTION and "code_actions" or null_ls.methods[method]:lower()
+ local source = type and null_ls.builtins[type][name]
+ Log:debug(string.format("Received request to register [%s] as a %s source", name, type))
+ if not source then
+ Log:error("Not a valid source: " .. name)
+ elseif is_registered { name = source.name or name, method = method } then
+ Log:trace(string.format("Skipping registering [%s] more than once", name))
+ else
+ local command = M.find_command(source._opts.command) or source._opts.command
+
+ -- treat `args` as `extra_args` for backwards compatibility. Can otherwise use `generator_opts.args`
+ local compat_opts = vim.deepcopy(config)
+ if config.args then
+ compat_opts.extra_args = config.args or config.extra_args
+ compat_opts.args = nil
+ end
+
+ local opts = vim.tbl_deep_extend("keep", { command = command }, compat_opts)
+ Log:debug("Registering source " .. name)
+ Log:trace(vim.inspect(opts))
+ table.insert(sources, source.with(opts))
+ vim.list_extend(registered_names, { source.name })
+ end
+ end
+
+ if #sources > 0 then
+ null_ls.register { sources = sources }
+ end
+ return registered_names
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/providers/jsonls.lua b/mac/.config/LunarVim/lua/lvim/lsp/providers/jsonls.lua
new file mode 100644
index 0000000..76aea25
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/providers/jsonls.lua
@@ -0,0 +1,18 @@
+local opts = {
+ settings = {
+ json = {
+ schemas = require("schemastore").json.schemas(),
+ },
+ },
+ setup = {
+ commands = {
+ Format = {
+ function()
+ vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 })
+ end,
+ },
+ },
+ },
+}
+
+return opts
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/providers/lua_ls.lua b/mac/.config/LunarVim/lua/lvim/lsp/providers/lua_ls.lua
new file mode 100644
index 0000000..952e04d
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/providers/lua_ls.lua
@@ -0,0 +1,64 @@
+local default_workspace = {
+ library = {
+ vim.fn.expand "$VIMRUNTIME",
+ get_lvim_base_dir(),
+ require("neodev.config").types(),
+ "${3rd}/busted/library",
+ "${3rd}/luassert/library",
+ "${3rd}/luv/library",
+ },
+
+ maxPreload = 5000,
+ preloadFileSize = 10000,
+}
+
+local add_packages_to_workspace = function(packages, config)
+ -- config.settings.Lua = config.settings.Lua or { workspace = default_workspace }
+ local runtimedirs = vim.api.nvim__get_runtime({ "lua" }, true, { is_lua = true })
+ local workspace = config.settings.Lua.workspace
+ for _, v in pairs(runtimedirs) do
+ for _, pack in ipairs(packages) do
+ if v:match(pack) and not vim.tbl_contains(workspace.library, v) then
+ table.insert(workspace.library, v)
+ end
+ end
+ end
+end
+
+local lspconfig = require "lspconfig"
+
+local make_on_new_config = function(on_new_config, _)
+ return lspconfig.util.add_hook_before(on_new_config, function(new_config, _)
+ local server_name = new_config.name
+
+ if server_name ~= "lua_ls" then
+ return
+ end
+ local plugins = { "plenary.nvim", "telescope.nvim", "nvim-treesitter", "LuaSnip" }
+ add_packages_to_workspace(plugins, new_config)
+ end)
+end
+
+lspconfig.util.default_config = vim.tbl_extend("force", lspconfig.util.default_config, {
+ on_new_config = make_on_new_config(lspconfig.util.default_config.on_new_config),
+})
+
+local opts = {
+ settings = {
+ Lua = {
+ telemetry = { enable = false },
+ runtime = {
+ version = "LuaJIT",
+ special = {
+ reload = "require",
+ },
+ },
+ diagnostics = {
+ globals = { "vim", "lvim", "reload" },
+ },
+ workspace = default_workspace,
+ },
+ },
+}
+
+return opts
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/providers/tailwindcss.lua b/mac/.config/LunarVim/lua/lvim/lsp/providers/tailwindcss.lua
new file mode 100644
index 0000000..ebf0a1c
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/providers/tailwindcss.lua
@@ -0,0 +1,15 @@
+local opts = {
+ root_dir = function(fname)
+ local util = require "lspconfig/util"
+ return util.root_pattern(
+ "tailwind.config.js",
+ "tailwind.config.ts",
+ "tailwind.config.cjs",
+ "tailwind.js",
+ "tailwind.ts",
+ "tailwind.cjs"
+ )(fname)
+ end,
+}
+
+return opts
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/providers/vuels.lua b/mac/.config/LunarVim/lua/lvim/lsp/providers/vuels.lua
new file mode 100644
index 0000000..326363f
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/providers/vuels.lua
@@ -0,0 +1,26 @@
+local opts = {
+ setup = {
+ root_dir = function(fname)
+ local util = require "lvim.lspconfig/util"
+ return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd()
+ end,
+ init_options = {
+ config = {
+ vetur = {
+ completion = {
+ autoImport = true,
+ tagCasing = "kebab",
+ useScaffoldSnippets = true,
+ },
+ useWorkspaceDependencies = true,
+ validation = {
+ script = true,
+ style = true,
+ template = true,
+ },
+ },
+ },
+ },
+ },
+}
+return opts
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/providers/yamlls.lua b/mac/.config/LunarVim/lua/lvim/lsp/providers/yamlls.lua
new file mode 100644
index 0000000..c9764fc
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/providers/yamlls.lua
@@ -0,0 +1,16 @@
+local opts = {
+ settings = {
+ yaml = {
+ hover = true,
+ completion = true,
+ validate = true,
+ schemaStore = {
+ enable = true,
+ url = "https://www.schemastore.org/api/json/catalog.json",
+ },
+ schemas = require("schemastore").yaml.schemas(),
+ },
+ },
+}
+
+return opts
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/templates.lua b/mac/.config/LunarVim/lua/lvim/lsp/templates.lua
new file mode 100644
index 0000000..4a65fac
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/templates.lua
@@ -0,0 +1,76 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+local utils = require "lvim.utils"
+local lvim_lsp_utils = require "lvim.lsp.utils"
+
+local ftplugin_dir = lvim.lsp.templates_dir
+
+local join_paths = _G.join_paths
+
+function M.remove_template_files()
+ -- remove any outdated files
+ for _, file in ipairs(vim.fn.glob(ftplugin_dir .. "/*.lua", 1, 1)) do
+ vim.fn.delete(file)
+ vim.wait(10)
+ end
+end
+
+local skipped_filetypes = lvim.lsp.automatic_configuration.skipped_filetypes
+local skipped_servers = lvim.lsp.automatic_configuration.skipped_servers
+
+---Check if we should skip generating an ftplugin file based on the server_name
+---@param server_name string name of a valid language server
+local function should_skip(server_name)
+ return vim.tbl_contains(skipped_servers, server_name)
+end
+
+---Generates an ftplugin file based on the server_name in the selected directory
+---@param server_name string name of a valid language server, e.g. pyright, gopls, tsserver, etc.
+---@param dir string the full path to the desired directory
+function M.generate_ftplugin(server_name, dir)
+ if should_skip(server_name) then
+ return
+ end
+
+ -- get the supported filetypes and remove any ignored ones
+ local filetypes = vim.tbl_filter(function(ft)
+ return not vim.tbl_contains(skipped_filetypes, ft)
+ end, lvim_lsp_utils.get_supported_filetypes(server_name) or {})
+
+ if not filetypes then
+ return
+ end
+
+ for _, filetype in ipairs(filetypes) do
+ filetype = filetype:match "%.([^.]*)$" or filetype
+ local filename = join_paths(dir, filetype .. ".lua")
+ local setup_cmd = string.format([[require("lvim.lsp.manager").setup(%q)]], server_name)
+ -- print("using setup_cmd: " .. setup_cmd)
+ -- overwrite the file completely
+ utils.write_file(filename, setup_cmd .. "\n", "a")
+ end
+end
+
+---Generates ftplugin files based on a list of server_names
+---The files are generated to a runtimepath: "$LUNARVIM_RUNTIME_DIR/site/after/ftplugin/template.lua"
+---@param servers_names? table list of servers to be enabled. Will add all by default
+function M.generate_templates(servers_names)
+ servers_names = servers_names or lvim_lsp_utils.get_supported_servers()
+
+ Log:debug "Templates installation in progress"
+
+ M.remove_template_files()
+
+ -- create the directory if it didn't exist
+ if not utils.is_directory(lvim.lsp.templates_dir) then
+ vim.fn.mkdir(ftplugin_dir, "p")
+ end
+
+ for _, server in ipairs(servers_names) do
+ M.generate_ftplugin(server, ftplugin_dir)
+ end
+ Log:debug "Templates installation is complete"
+end
+
+return M
diff --git a/mac/.config/LunarVim/lua/lvim/lsp/utils.lua b/mac/.config/LunarVim/lua/lvim/lsp/utils.lua
new file mode 100644
index 0000000..0d9bcd7
--- /dev/null
+++ b/mac/.config/LunarVim/lua/lvim/lsp/utils.lua
@@ -0,0 +1,185 @@
+local M = {}
+
+local tbl = require "lvim.utils.table"
+local Log = require "lvim.core.log"
+
+function M.is_client_active(name)
+ local clients = vim.lsp.get_clients()
+ return tbl.find_first(clients, function(client)
+ return client.name == name
+ end)
+end
+
+function M.get_active_clients_by_ft(filetype)
+ local matches = {}
+ local clients = vim.lsp.get_clients()
+ for _, client in pairs(clients) do
+ local supported_filetypes = client.config.filetypes or {}
+ if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then
+ table.insert(matches, client)
+ end
+ end
+ return matches
+end
+
+function M.get_client_capabilities(client_id)
+ local client = vim.lsp.get_client_by_id(tonumber(client_id))
+ if not client then
+ Log:warn("Unable to determine client from client_id: " .. client_id)
+ return
+ end
+
+ local enabled_caps = {}
+ for capability, status in pairs(client.server_capabilities) do
+ if status == true then
+ table.insert(enabled_caps, capability)
+ end
+ end
+
+ return enabled_caps
+end
+
+---Get supported filetypes per server
+---@param server_name string can be any server supported by nvim-lsp-installer
+---@return string[] supported filestypes as a list of strings
+function M.get_supported_filetypes(server_name)
+ local status_ok, config = pcall(require, ("lspconfig.server_configurations.%s"):format(server_name))
+ if not status_ok then
+ return {}
+ end
+
+ return config.default_config.filetypes or {}
+end
+
+---Get supported servers per filetype
+---@param filter { filetype: string | string[] }?: (optional) Used to filter the list of server names.
+---@return string[] list of names of supported servers
+function M.get_supported_servers(filter)
+ -- force synchronous mode, see: |mason-registry.refresh()|
+ require("mason-registry").refresh()
+ require("mason-registry").get_all_packages()
+
+ local _, supported_servers = pcall(function()
+ return require("mason-lspconfig").get_available_servers(filter)
+ end)
+ return supported_servers or {}
+end
+
+---Get all supported filetypes by nvim-lsp-installer
+---@return string[] supported filestypes as a list of strings
+function M.get_all_supported_filetypes()
+ local status_ok, filetype_server_map = pcall(require, "mason-lspconfig.mappings.filetype")
+ if not status_ok then
+ return {}
+ end
+ return vim.tbl_keys(filetype_server_map or {})
+end
+
+function M.setup_document_highlight(client, bufnr)
+ if lvim.builtin.illuminate.active then
+ Log:debug "skipping setup for document_highlight, illuminate already active"
+ return
+ end
+ local status_ok, highlight_supported = pcall(function()
+ return client.supports_method "textDocument/documentHighlight"
+ end)
+ if not status_ok or not highlight_supported then
+ return
+ end
+ local group = "lsp_document_highlight"
+ local hl_events = { "CursorHold", "CursorHoldI" }
+
+ local ok, hl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+ group = group,
+ buffer = bufnr,
+ event = hl_events,
+ })
+
+ if ok and #hl_autocmds > 0 then
+ return
+ end
+
+ vim.api.nvim_create_augroup(group, { clear = false })
+ vim.api.nvim_create_autocmd(hl_events, {
+ group = group,
+ buffer = bufnr,
+ callback = vim.lsp.buf.document_highlight,
+ })
+ vim.api.nvim_create_autocmd("CursorMoved", {
+ group = group,
+ buffer = bufnr,
+ callback = vim.lsp.buf.clear_references,
+ })
+end
+
+function M.setup_document_symbols(client, bufnr)
+ vim.g.navic_silence = false -- can be set to true to suppress error
+ local symbols_supported = client.supports_method "textDocument/documentSymbol"
+ if not symbols_supported then
+ Log:debug("skipping setup for document_symbols, method not supported by " .. client.name)
+ return
+ end
+ local status_ok, navic = pcall(require, "nvim-navic")
+ if status_ok then
+ navic.attach(client, bufnr)
+ end
+end
+
+function M.setup_codelens_refresh(client, bufnr)
+ local status_ok, codelens_supported = pcall(function()
+ return client.supports_method "textDocument/codeLens"
+ end)
+ if not status_ok or not codelens_supported then
+ return
+ end
+ local group = "lsp_code_lens_refresh"
+ local cl_events = { "BufEnter", "InsertLeave" }
+ local ok, cl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+ group = group,
+ buffer = bufnr,
+ event = cl_events,
+ })
+
+ if ok and #cl_autocmds > 0 then
+ return
+ end
+ vim.api.nvim_create_augroup(group, { clear = false })
+ vim.api.nvim_create_autocmd(cl_events, {
+ group = group,
+ buffer = bufnr,
+ callback = function()
+ vim.lsp.codelens.refresh { bufnr = bufnr }
+ end,
+ })
+end
+
+---filter passed to vim.lsp.buf.format
+---always selects null-ls if it's available and caches the value per buffer
+---@param client table client attached to a buffer
+---@return boolean if client matches
+function M.format_filter(client)
+ local filetype = vim.bo.filetype
+ local n = require "null-ls"
+ local s = require "null-ls.sources"
+ local method = n.methods.FORMATTING
+ local available_formatters = s.get_available(filetype, method)
+
+ if #available_formatters > 0 then
+ return client.name == "null-ls"
+ elseif client.supports_method "textDocument/formatting" then
+ return true
+ else
+ return false
+ end
+end
+
+---Simple wrapper for vim.lsp.buf.format() to provide defaults
+---@param opts table|nil
+function M.format(opts)
+ opts = opts or {}
+ opts.filter = opts.filter or M.format_filter
+
+ return vim.lsp.buf.format(opts)
+end
+
+return M