diff options
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/mason-core/optional.lua | 8 | ||||
| -rw-r--r-- | lua/mason-lspconfig/api/command.lua | 141 | ||||
| -rw-r--r-- | lua/mason-lspconfig/init.lua | 2 | ||||
| -rw-r--r-- | lua/mason-lspconfig/mappings/server.lua | 2 | ||||
| -rw-r--r-- | lua/mason-schemas/lsp/deno.lua (renamed from lua/mason-schemas/lsp/deno-lsp.lua) | 0 | ||||
| -rw-r--r-- | lua/mason/api/command.lua | 44 | ||||
| -rw-r--r-- | lua/mason/mappings/language.lua | 103 | ||||
| -rw-r--r-- | lua/mason/ui/init.lua | 11 | ||||
| -rw-r--r-- | lua/mason/ui/instance.lua | 7 |
9 files changed, 297 insertions, 21 deletions
diff --git a/lua/mason-core/optional.lua b/lua/mason-core/optional.lua index 10af8ccb..5710ce0c 100644 --- a/lua/mason-core/optional.lua +++ b/lua/mason-core/optional.lua @@ -93,6 +93,14 @@ function Optional:if_present(fn) return self end +---@param fn fun(value: any) +function Optional:if_not_present(fn) + if not self:is_present() then + fn(self._value) + end + return self +end + function Optional:is_present() return self._value ~= nil end diff --git a/lua/mason-lspconfig/api/command.lua b/lua/mason-lspconfig/api/command.lua new file mode 100644 index 00000000..22a96be5 --- /dev/null +++ b/lua/mason-lspconfig/api/command.lua @@ -0,0 +1,141 @@ +local a = require "mason-core.async" +local Optional = require "mason-core.optional" +local notify = require "mason-core.notify" +local _ = require "mason-core.functional" + +local M = {} + +---@async +---@param user_args string[] @The arguments, as provided by the user. +local function parse_packages_from_user_args(user_args) + local Package = require "mason-core.package" + local server_mapping = require "mason-lspconfig.mappings.server" + local language_mapping = require "mason.mappings.language" + + return _.filter_map(function(server_specifier) + local server_name, version = Package.Parse(server_specifier) + -- 1. first see if the provided arg is an actual lspconfig server name + return Optional + .of_nilable(server_mapping.lspconfig_to_package[server_name]) + -- 2. if not, check if it's a language specifier (e.g., "typescript" or "java") + :or_(function() + return Optional.of_nilable(language_mapping[server_name]):map(function(package_names) + local lsp_package_names = _.filter(function(package_name) + return server_mapping.package_to_lspconfig[package_name] ~= nil + end, package_names) + + if #lsp_package_names == 0 then + return nil + end + + return a.promisify(vim.ui.select)(lsp_package_names, { + prompt = ("Please select which server you want to install for language %q:"):format( + server_name + ), + format_item = function(item) + return server_mapping.package_to_lspconfig[item] + end, + }) + end) + end) + :map(function(package_name) + return { package = package_name, version = version } + end) + :if_not_present(function() + notify(("Could not find LSP server %q."):format(server_name), vim.log.levels.ERROR) + end) + end, user_args) +end + +---@async +local function parse_packages_from_heuristics() + local server_mapping = require "mason-lspconfig.mappings.server" + + -- Prompt user which server they want to install (based on the current filetype) + local current_ft = vim.api.nvim_buf_get_option(vim.api.nvim_get_current_buf(), "filetype") + local filetype_mapping = require "mason-lspconfig.mappings.filetype" + return Optional.of_nilable(filetype_mapping[current_ft]) + :map(function(server_names) + return a.promisify(vim.ui.select)(server_names, { + prompt = ("Please select which server you want to install for filetype %q:"):format(current_ft), + }) + end) + :map(function(server_name) + local package_name = server_mapping.lspconfig_to_package[server_name] + return { package = package_name, version = nil } + end) + :or_else_get(function() + notify(("No LSP servers found for filetype %q."):format(current_ft), vim.log.levels.ERROR) + return {} + end) +end + +local parse_packages_to_install = _.cond { + { _.compose(_.gt(0), _.length), parse_packages_from_user_args }, + { _.compose(_.equals(0), _.length), parse_packages_from_heuristics }, + { _.T, _.always {} }, +} + +vim.api.nvim_create_user_command( + "LspInstall", + a.scope(function(opts) + local packages_to_install = parse_packages_to_install(opts.fargs) + if #packages_to_install > 0 then + local registry = require "mason-registry" + _.each(function(target) + local pkg = registry.get_package(target.package) + pkg:install { version = target.version } + end, packages_to_install) + require("mason.ui").open() + require("mason.ui").set_view "LSP" + end + end), + { + desc = "Install one or more LSP servers.", + nargs = "*", + complete = "custom,v:lua.mason_lspconfig_completion.available_server_completion", + } +) + +vim.api.nvim_create_user_command("LspUninstall", function(opts) + require("mason.ui").open() + require("mason.ui").set_view "LSP" + local registry = require "mason-registry" + local server_mapping = require "mason-lspconfig.mappings.server" + for _, server_specifier in ipairs(opts.fargs) do + local package_name = server_mapping.lspconfig_to_package[server_specifier] + local pkg = registry.get_package(package_name) + pkg:uninstall() + end +end, { + desc = "Uninstall one or more LSP servers.", + nargs = "+", + complete = "custom,v:lua.mason_lspconfig_completion.installed_server_completion", +}) + +_G.mason_lspconfig_completion = { + available_server_completion = function() + local registry = require "mason-registry" + local server_mapping = require "mason-lspconfig.mappings.server" + local language_mapping = require "mason.mappings.language" + + local package_names = _.filter_map(function(pkg_name) + return Optional.of_nilable(server_mapping.package_to_lspconfig[pkg_name]) + end, registry.get_all_package_names()) + local completion = _.concat(package_names, _.keys(language_mapping)) + table.sort(completion) + return table.concat(completion, "\n") + end, + installed_server_completion = function() + local registry = require "mason-registry" + local server_mapping = require "mason-lspconfig.mappings.server" + + local server_names = _.filter_map(function(pkg_name) + return Optional.of_nilable(server_mapping.package_to_lspconfig[pkg_name]) + end, registry.get_installed_package_names()) + table.sort(server_names) + return table.concat(server_names, "\n") + end, +} + +return M diff --git a/lua/mason-lspconfig/init.lua b/lua/mason-lspconfig/init.lua index 67f4cd16..8682d2e8 100644 --- a/lua/mason-lspconfig/init.lua +++ b/lua/mason-lspconfig/init.lua @@ -103,6 +103,8 @@ function M.setup(config) setup_lspconfig_hook() ensure_installed() + + require "mason-lspconfig.api.command" end ---@param handlers table<string, fun(server_name: string)> diff --git a/lua/mason-lspconfig/mappings/server.lua b/lua/mason-lspconfig/mappings/server.lua index 9d784c9b..582963f4 100644 --- a/lua/mason-lspconfig/mappings/server.lua +++ b/lua/mason-lspconfig/mappings/server.lua @@ -27,7 +27,7 @@ M.lspconfig_to_package = { ["cssls"] = "css-lsp", ["cssmodules_ls"] = "cucumber-language-server", ["cucumber_language_server"] = "cucumber-language-server", - ["denols"] = "deno-lsp", + ["denols"] = "deno", ["dhall_lsp_server"] = "dhall-lsp", ["diagnosticls"] = "diagnostic-languageserver", ["dockerls"] = "dockerfile-language-server", diff --git a/lua/mason-schemas/lsp/deno-lsp.lua b/lua/mason-schemas/lsp/deno.lua index 5ad46765..5ad46765 100644 --- a/lua/mason-schemas/lsp/deno-lsp.lua +++ b/lua/mason-schemas/lsp/deno.lua diff --git a/lua/mason/api/command.lua b/lua/mason/api/command.lua index f3540fd9..064477f4 100644 --- a/lua/mason/api/command.lua +++ b/lua/mason/api/command.lua @@ -1,4 +1,5 @@ local notify = require "mason-core.notify" +local _ = require "mason-core.functional" local M = {} @@ -9,18 +10,30 @@ end, { nargs = 0, }) +-- This is needed because neovim doesn't do any validation of command args when using custom completion (I think?) +local filter_valid_packages = _.filter(function(pkg_specifier) + local Package = require "mason-core.package" + local registry = require "mason-registry" + local package_name = Package.Parse(pkg_specifier) + local ok = pcall(registry.get_package, package_name) + if ok then + return true + else + notify(("%q is not a valid package."):format(pkg_specifier), vim.log.levels.ERROR) + return false + end +end) + vim.api.nvim_create_user_command("MasonInstall", function(opts) local Package = require "mason-core.package" local registry = require "mason-registry" - for _, package_specifier in ipairs(opts.fargs) do - ---@type string - local package_name, version = Package.Parse(package_specifier) - local ok, pkg = pcall(registry.get_package, package_name) - if not ok then - notify(("Cannot find package %q."):format(package_name), vim.log.levels.ERROR) - return - end - local handle = pkg:install { version = version } + local valid_packages = filter_valid_packages(opts.fargs) + if #valid_packages > 0 then + _.each(function(pkg_specifier) + local package_name, version = Package.Parse(pkg_specifier) + local pkg = registry.get_package(package_name) + pkg:install { version = version } + end, valid_packages) require("mason.ui").open() end end, { @@ -31,13 +44,12 @@ end, { vim.api.nvim_create_user_command("MasonUninstall", function(opts) local registry = require "mason-registry" - for _, package_name in ipairs(opts.fargs) do - local ok, pkg = pcall(registry.get_package, package_name) - if not ok then - notify(("Cannot find package %q."):format(package_name), vim.log.levels.ERROR) - return - end - pkg:uninstall() + local valid_packages = filter_valid_packages(opts.fargs) + if #valid_packages > 0 then + _.each(function(package_name) + local pkg = registry.get_package(package_name) + pkg:uninstall() + end, filter_valid_packages) require("mason.ui").open() end end, { diff --git a/lua/mason/mappings/language.lua b/lua/mason/mappings/language.lua new file mode 100644 index 00000000..b005d2da --- /dev/null +++ b/lua/mason/mappings/language.lua @@ -0,0 +1,103 @@ +-- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY. +-- stylua: ignore start +return { + [".net"] = { "netcoredbg" }, + ["1ะก:enterprise"] = { "bsl-language-server" }, + angular = { "angular-language-server" }, + ansible = { "ansible-language-server" }, + apex = { "apex-language-server" }, + arduino = { "arduino-language-server" }, + assembly = { "asm-lsp" }, + astro = { "astro-language-server" }, + awk = { "awk-language-server" }, + bash = { "bash-language-server", "shellcheck" }, + beancount = { "beancount-language-server" }, + bicep = { "bicep-lsp" }, + c = { "ccls", "clangd", "codelldb", "cpptools" }, + ["c#"] = { "csharp-language-server", "netcoredbg", "omnisharp-roslyn" }, + ["c++"] = { "ccls", "clangd", "codelldb", "cpptools" }, + clarity = { "clarity-lsp" }, + clojure = { "clojure-lsp" }, + clojurescript = { "clojure-lsp" }, + cmake = { "cmake-language-server" }, + codeql = { "codeql" }, + crystal = { "crystalline" }, + css = { "css-lsp", "cssmodules-language-server", "tailwindcss-language-server" }, + cucumber = { "cucumber-language-server" }, + d = { "serve-d" }, + dhall = { "dhall-lsp" }, + dockerfile = { "dockerfile-language-server" }, + dot = { "dot-language-server" }, + elixir = { "elixir-ls" }, + elm = { "elm-format", "elm-language-server" }, + ember = { "ember-language-server" }, + emmet = { "emmet-ls" }, + erlang = { "erlang-ls" }, + ["f#"] = { "fsautocomplete" }, + flux = { "flux-lsp" }, + fortran = { "fortls" }, + go = { "delve", "go-debug-adapter", "golangci-lint", "golangci-lint-langserver", "gomodifytags", "gopls", "gotests", "impl" }, + graphql = { "graphql-language-service-cli" }, + groovy = { "groovy-language-server" }, + haskell = { "haskell-language-server" }, + haxe = { "haxe-language-server" }, + hoon = { "hoon-language-server" }, + html = { "html-lsp" }, + java = { "jdtls" }, + javascript = { "chrome-debug-adapter", "deno", "eslint-lsp", "eslint_d", "firefox-debug-adapter", "node-debug2-adapter", "quick-lint-js", "rome", "typescript-language-server" }, + json = { "json-lsp" }, + jsonnet = { "jsonnet-language-server" }, + julia = { "julia-lsp" }, + kotlin = { "kotlin-language-server", "ktlint" }, + latex = { "ltex-ls", "texlab" }, + lelwel = { "lelwel" }, + less = { "css-lsp" }, + liquid = { "shopify-theme-check" }, + lua = { "lemmy-help", "lua-language-server", "stylua" }, + markdown = { "grammarly-languageserver", "ltex-ls", "marksman", "prosemd-lsp", "remark-language-server", "zk" }, + ["metamath zero"] = { "metamath-zero-lsp" }, + nickel = { "nickel-lang-lsp" }, + nim = { "nimlsp" }, + nix = { "rnix-lsp" }, + ["obective-c"] = { "ccls" }, + ocaml = { "ocaml-lsp" }, + onescript = { "bsl-language-server" }, + opencl = { "opencl-language-server" }, + openfoam = { "foam-language-server" }, + perl = { "perlnavigator" }, + php = { "intelephense", "php-debug-adapter", "phpactor", "psalm" }, + powershell = { "powershell-editor-services" }, + prisma = { "prisma-language-server" }, + puppet = { "puppet-editor-services" }, + purescript = { "purescript-language-server" }, + python = { "debugpy", "jedi-language-server", "pyright", "python-lsp-server", "sourcery" }, + r = { "r-languageserver" }, + reason = { "reason-language-server" }, + rescript = { "rescript-lsp" }, + ["robot framework"] = { "robotframework-lsp" }, + ruby = { "solargraph", "sorbet" }, + rust = { "codelldb", "cpptools", "rust-analyzer" }, + salt = { "salt-lsp" }, + scss = { "css-lsp" }, + slint = { "slint-lsp" }, + solidity = { "solang", "solidity" }, + sphinx = { "esbonio" }, + sql = { "sqlls", "sqls" }, + stylelint = { "stylelint-lsp" }, + svelte = { "svelte-language-server" }, + systemverilog = { "svlangserver", "svls", "verible" }, + teal = { "teal-language-server" }, + terraform = { "terraform-ls", "tflint" }, + text = { "grammarly-languageserver", "ltex-ls" }, + toml = { "taplo" }, + typescript = { "chrome-debug-adapter", "deno", "eslint-lsp", "eslint_d", "firefox-debug-adapter", "node-debug2-adapter", "rome", "typescript-language-server" }, + v = { "vls" }, + vala = { "vala-language-server" }, + vimscript = { "vim-language-server" }, + visualforce = { "visualforce-language-server" }, + vue = { "vetur-vls", "vue-language-server" }, + wgsl = { "wgsl-analyzer" }, + xml = { "lemminx" }, + yaml = { "yaml-language-server" }, + zig = { "zls" } +}
\ No newline at end of file diff --git a/lua/mason/ui/init.lua b/lua/mason/ui/init.lua index 56b0b382..2181a555 100644 --- a/lua/mason/ui/init.lua +++ b/lua/mason/ui/init.lua @@ -1,11 +1,16 @@ local settings = require "mason.settings" local M = {} -M.open = function() - local window = require "mason.ui.instance" - window.open { +function M.open() + local api = require "mason.ui.instance" + api.window.open { border = settings.current.ui.border, } end +function M.set_view(view) + local api = require "mason.ui.instance" + api.set_view(view) +end + return M diff --git a/lua/mason/ui/instance.lua b/lua/mason/ui/instance.lua index 95ebe20f..beb73705 100644 --- a/lua/mason/ui/instance.lua +++ b/lua/mason/ui/instance.lua @@ -604,4 +604,9 @@ window.init { highlight_groups = palette.highlight_groups, } -return window +return { + window = window, + set_view = function(view) + set_view { payload = view } + end, +} |
