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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
local a = require "nvim-lsp-installer.core.async"
local Path = require "nvim-lsp-installer.core.path"
local fetch = require "nvim-lsp-installer.core.fetch"
local _ = require "nvim-lsp-installer.core.functional"
local servers = require "nvim-lsp-installer.servers"
local fs = require "nvim-lsp-installer.core.fs"
local generated_dir = Path.concat { vim.fn.getcwd(), "lua", "nvim-lsp-installer", "_generated" }
local schemas_dir = Path.concat { generated_dir, "schemas" }
print("Creating directory " .. generated_dir)
vim.fn.mkdir(generated_dir, "p")
print("Creating directory " .. schemas_dir)
vim.fn.mkdir(schemas_dir, "p")
for _, file in ipairs(vim.fn.glob(Path.concat { generated_dir, "*" }, 1, 1)) do
print("Deleting " .. file)
vim.fn.delete(file)
end
for _, file in ipairs(vim.fn.glob(Path.concat { schemas_dir, "*" }, 1, 1)) do
print("Deleting " .. file)
vim.fn.delete(file)
end
---@async
---@param path string
---@param contents string
---@param flags string
local function write_file(path, contents, flags)
fs.async.write_file(
path,
table.concat({
"-- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY.",
"-- stylua: ignore start",
contents,
}, "\n"),
flags
)
end
local function get_lspconfig(name)
return require(("lspconfig.server_configurations.%s"):format(name))
end
---@param server Server
local function get_supported_filetypes(server)
local config = get_lspconfig(server.name)
local default_options = server:get_default_options()
local filetypes = _.coalesce(
-- nvim-lsp-installer options has precedence
default_options and default_options.filetypes,
config.default_config.filetypes,
{}
)
return filetypes
end
---@async
local function create_filetype_map()
local filetype_map = {}
local available_servers = servers.get_available_servers()
for _, server in pairs(available_servers) do
for _, filetype in pairs(get_supported_filetypes(server)) do
if not filetype_map[filetype] then
filetype_map[filetype] = {}
end
table.insert(filetype_map[filetype], server.name)
table.sort(filetype_map[filetype])
end
end
write_file(Path.concat { generated_dir, "filetype_map.lua" }, "return " .. vim.inspect(filetype_map), "w")
end
---@async
local function create_autocomplete_map()
---@type table<string, Server>
local language_map = {}
local available_servers = servers.get_available_servers()
for _, server in pairs(available_servers) do
local languages = server.languages
for _, language in pairs(languages) do
if not language_map[language] then
language_map[language] = {}
end
table.insert(language_map[language], server)
end
end
local autocomplete_candidates = {}
for language, language_servers in pairs(language_map) do
local non_deprecated_servers = _.filter(_.prop_eq("deprecated", nil), language_servers)
local is_candidate = #non_deprecated_servers > 0
if #non_deprecated_servers == 1 then
local server = non_deprecated_servers[1]
is_candidate = not vim.startswith(server.name, language)
end
if is_candidate then
autocomplete_candidates[language] = _.map(_.prop "name", non_deprecated_servers)
table.sort(autocomplete_candidates[language])
end
end
write_file(
Path.concat { generated_dir, "language_autocomplete_map.lua" },
"return " .. vim.inspect(autocomplete_candidates),
"w"
)
end
---@async
local function create_server_metadata()
local metadata = {}
---@param server Server
local function create_metadata_entry(server)
return { filetypes = get_supported_filetypes(server) }
end
local available_servers = servers.get_available_servers()
for _, server in pairs(available_servers) do
metadata[server.name] = create_metadata_entry(server)
end
write_file(Path.concat { generated_dir, "metadata.lua" }, "return " .. vim.inspect(metadata), "w")
end
---@async
local function create_setting_schema_files()
local available_servers = servers.get_available_servers()
local gist_data = fetch(
"https://gist.githubusercontent.com/williamboman/a01c3ce1884d4b57cc93422e7eae7702/raw/lsp-packages.json"
):get_or_throw()
local package_json_mappings = vim.json.decode(gist_data)
for _, server in pairs(available_servers) do
local package_json_url = package_json_mappings[server.name]
if package_json_url then
print(("Fetching %q..."):format(package_json_url))
local response = fetch(package_json_url):get_or_throw()
local schema = vim.json.decode(response)
if schema.contributes and schema.contributes.configuration then
schema = schema.contributes.configuration
end
if not schema.properties then
-- Some servers (like dartls) seem to provide an array of configurations (for more than just LSP stuff)
print(("Could not find appropriate schema structure for %s."):format(server.name))
else
write_file(
Path.concat { schemas_dir, ("%s.lua"):format(server.name) },
"return " .. vim.inspect(schema, { newline = "", indent = "" }),
"w"
)
end
end
end
end
a.run_blocking(function()
a.wait_all {
create_filetype_map,
create_autocomplete_map,
create_server_metadata,
create_setting_schema_files,
}
end)
|