1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
local a = require "mason-core.async"
local Optional = require "mason-core.optional"
local notify = require "mason-core.notify"
local _ = require "mason-core.functional"
---@async
---@param user_args string[]: The arguments, as provided by the user.
local function parse_packages_from_user_args(user_args)
local registry = require "mason-registry"
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 package_names = _.filter(function(package_name)
return server_mapping.package_to_lspconfig[package_name] ~= nil
end, package_names)
if #package_names == 0 then
return nil
end
return a.promisify(vim.ui.select)(package_names, {
prompt = ("Please select which server you want to install for language %q:"):format(
server_name
),
format_item = function(package_name)
local server_name = server_mapping.package_to_lspconfig[package_name]
if registry.is_installed(package_name) then
return ("%s (installed)"):format(server_name)
else
return server_name
end
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"
local registry = require "mason-registry"
-- 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),
format_item = function(server_name)
if registry.is_installed(server_mapping.lspconfig_to_package[server_name]) then
return ("%s (installed)"):format(server_name)
else
return server_name
end
end,
})
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 {} },
}
local LspInstall = a.scope(function(servers)
local packages_to_install = parse_packages_to_install(servers)
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)
local ui = require "mason.ui"
ui.open()
ui.set_view "LSP"
vim.schedule(function()
ui.set_sticky_cursor "installing-section"
end)
end
end)
vim.api.nvim_create_user_command("LspInstall", function(opts)
LspInstall(opts.fargs)
end, {
desc = "Install one or more LSP servers.",
nargs = "*",
complete = "custom,v:lua.mason_lspconfig_completion.available_server_completion",
})
local function LspUninstall(servers)
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(servers) do
local package_name = server_mapping.lspconfig_to_package[server_specifier]
local pkg = registry.get_package(package_name)
pkg:uninstall()
end
end
vim.api.nvim_create_user_command("LspUninstall", function(opts)
LspUninstall(opts.fargs)
end, {
desc = "Uninstall one or more LSP servers.",
nargs = "+",
complete = "custom,v:lua.mason_lspconfig_completion.installed_server_completion",
})
-- selene: allow(global_usage)
_G.mason_lspconfig_completion = {
available_server_completion = function()
local available_servers = require("mason-lspconfig").get_available_servers()
local language_mapping = require "mason.mappings.language"
local sort_deduped = _.compose(_.sort_by(_.identity), _.uniq_by(_.identity))
local completions = sort_deduped(_.concat(_.keys(language_mapping), available_servers))
return table.concat(completions, "\n")
end,
installed_server_completion = function()
local installed_servers = require("mason-lspconfig").get_installed_servers()
return table.concat(installed_servers, "\n")
end,
}
return {
LspInstall = LspInstall,
LspUninstall = LspUninstall,
}
|