-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added sumneko annotations for lsp server settings!
- Loading branch information
Showing
4 changed files
with
13,148 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.