aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/autogen_metadata.lua
blob: 29339ce1b8a73369ec0143d813165821de2a5d31 (plain) (blame)
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
local a = require "mason-core.async"
local Path = require "mason-core.path"
local fetch = require "mason-core.fetch"
local _ = require "mason-core.functional"
local fs = require "mason-core.fs"
local lspconfig_server_mapping = require "mason-lspconfig.mappings.server"

---@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

---@async
local function create_lspconfig_filetype_map()
    local filetype_map = {}

    for _, server_name in ipairs(_.keys(lspconfig_server_mapping.lspconfig_to_package)) do
        local config = get_lspconfig(server_name)
        for _, filetype in ipairs(config.default_config.filetypes or {}) 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 { vim.loop.cwd(), "lua", "mason-lspconfig", "mappings", "filetype.lua" },
        "return " .. vim.inspect(filetype_map),
        "w"
    )
end

---@async
local function create_lsp_setting_schema_files()
    local lsp_schemas_path = Path.concat {
        vim.loop.cwd(),
        "lua",
        "mason-schemas",
        "lsp",
    }

    for _, file in
        ipairs(vim.fn.glob(
            Path.concat {
                lsp_schemas_path,
                "*",
            },
            1,
            1
        ))
    do
        print("Deleting " .. file)
        vim.fn.delete(file)
    end

    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_name in ipairs(_.keys(lspconfig_server_mapping.lspconfig_to_package)) 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 {
                        lsp_schemas_path,
                        ("%s.lua"):format(lspconfig_server_mapping.lspconfig_to_package[server_name]),
                    },
                    "return " .. vim.inspect(schema, { newline = "", indent = "" }),
                    "w"
                )
            end
        end
    end
end

---@async
local function create_package_index()
    a.scheduler()
    local packages = {}
    local to_lua_path = _.compose(_.gsub("/", "."), _.gsub("^lua/", ""))
    for _, package_path in ipairs(vim.fn.glob("lua/mason-registry/*/init.lua", false, true)) do
        local package_filename = vim.fn.fnamemodify(package_path, ":h:t")
        local lua_path = to_lua_path(vim.fn.fnamemodify(package_path, ":h"))
        local pkg = require(lua_path)
        assert(package_filename == pkg.name, ("Package name is not the same as its module name %s"):format(lua_path))
        packages[pkg.name] = lua_path
    end

    write_file(
        Path.concat { vim.loop.cwd(), "lua", "mason-registry", "index.lua" },
        "return " .. vim.inspect(packages),
        "w"
    )
end

a.run_blocking(function()
    a.wait_all(_.filter(_.identity, {
        create_lspconfig_filetype_map,
        not vim.env.SKIP_SCHEMAS and create_lsp_setting_schema_files,
        create_package_index,
    }))
end)