Skip to content

Commit

Permalink
feat: added sumneko annotations for lsp server settings!
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Sep 9, 2022
1 parent 40c894a commit d824aff
Show file tree
Hide file tree
Showing 4 changed files with 13,148 additions and 7 deletions.
191 changes: 191 additions & 0 deletions lua/settings/build/annotations.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
local util = require("settings.util")
local Schema = require("settings.schema")

local M = {}

M.class_name = ""
M.lines = {}

function M.table_key(str)
if str:match("[^%a_]") then
return "[" .. vim.inspect(str) .. "]"
end
return str
end

function M.comment(desc, prefix)
if desc then
prefix = (prefix or "") .. "-- "
return prefix .. desc:gsub("\n", "\n" .. prefix)
end
end

function M.add_desc(lines, prop, prefix)
local ret = prop.markdownDescription or prop.description
if prop.default then
if prop.default == vim.NIL then
prop.default = nil
end
if type(prop.default) == "table" and vim.tbl_isempty(prop.default) then
prop.default = {}
end
ret = (ret and (ret .. "\n\n") or "") .. "```lua\ndefault = " .. vim.inspect(prop.default) .. "\n```"
end
if ret then
table.insert(lines, M.comment(ret, prefix))
end
end

function M.fix_props(node)
return node.leaf and node
or {
type = "object",
properties = vim.tbl_map(function(child)
return M.fix_props(child)
end, node),
}
end

function M.get_class(name)
if name == M.class_name then
return name
end
local ret = { M.class_name }
for word in string.gmatch(name, "([^_]+)") do
table.insert(ret, word:sub(1, 1):upper() .. word:sub(2))
end
return table.concat(ret, ".")
end

function M.get_type(prop)
if prop.enum then
return table.concat(
vim.tbl_map(function(e)
return vim.inspect(e)
end, prop.enum),
" | "
)
end
local types = type(prop.type) == "table" and prop.type or { prop.type }
types = vim.tbl_map(function(t)
if t == "null" then
return
end
if t == "array" then
if prop.items and prop.items.type then
if type(prop.items.type) == "table" then
prop.items.type = "any"
end
return prop.items.type .. "[]"
end
end
if t == "object" then
return "table"
end
return t
end, types)
return table.concat(vim.tbl_flatten(types), "|")
end

function M.process_object(name, prop)
local lines = {}
M.add_desc(lines, prop)
table.insert(lines, "---@class " .. M.get_class(name))
if prop.properties then
for field, child in pairs(prop.properties) do
M.add_desc(lines, child)

if child.type == "object" and child.properties then
table.insert(lines, "---@field " .. field .. " " .. M.get_class(field))
M.process_object(field, child)
else
table.insert(lines, "---@field " .. field .. " " .. M.get_type(child))
end
end
end
table.insert(M.lines, "")
vim.list_extend(M.lines, lines)
end

function M.process_prop(lines, name, prop)
if prop.type == "object" then
error("should not happen")
end

table.insert(lines, " " .. M.table_key(name) .. " = " .. vim.inspect(prop.default) .. ",")
end

function M.build_annotations(name)
local file = util.path("schemas/" .. name .. ".json")
local json = util.json_decode(util.read_file(file)) or {}
M.class_name = "Settings." .. name

local schema = require("settings.settings").new()
for key, prop in pairs(json.properties) do
prop.leaf = true
schema:set(key, prop)
end

M.process_object(M.class_name, M.fix_props(schema:get()))
end

function M.build_lspconfig()
local str = [[---@meta
---@class LspConfigOptions
---@field root_dir fun(filename, bufnr): string|nil
---@field name string
---@field filetypes string[] | nil
---@field autostart boolean
---@field single_file_support boolean
---@field on_new_config fun(new_config, new_root_dir)
---@field capabilities table
---@field cmd string[]
---@field handlers table<string, fun()>
---@field init_options table
---@field on_attach fun(client, bufnr)
---@module 'lspconfig'
local lspconfig
]]

local index = Schema.get_lsp_schemas()
for name, _ in pairs(index) do
str = str
.. ([[
---@class LspConfigOptions.%s: LspConfigOptions
---@field settings Settings.%s
lspconfig.%s = {
---@param options LspConfigOptions.%s
setup = function(options) end,
}
]]):format(name, name, name, name)
end

str = str .. "\n---@class LspConfigSettings\n"
for name, _ in pairs(index) do
str = str .. ("---@field %s LspConfigOptions.%s\n"):format(name, name)
end

str = str .. "\n\n return lspconfig"
util.write_file("types/lua/lspconfig.lua", str)
end

function M.build()
M.lines = { "---@meta\n" }
local index = Schema.get_lsp_schemas()
for name, _ in pairs(index) do
M.build_annotations(name)
end

local lines = vim.tbl_filter(function(v)
return v ~= nil
end, M.lines)
util.write_file("types/lsp.lua", table.concat(lines, "\n"))
M.build_lspconfig()
end

return M
11 changes: 4 additions & 7 deletions lua/settings/build/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,10 @@ function M.update_schemas()
end

function M.build()
-- vim.fn.mkdir("build", "p")
-- M.clean()
-- M.update_index()
-- M.update_schemas()
M.build_types({ sumneko_lua = "" })

-- M.build_types()
M.clean()
M.update_index()
M.update_schemas()
require("settings.build.annotations").build()
end

M.build()
Expand Down
Loading

0 comments on commit d824aff

Please sign in to comment.