diff options
| author | Ashkan Kiani <ashkan.k.kiani@gmail.com> | 2019-11-17 12:27:06 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-17 12:27:06 -0800 |
| commit | 43c7040614dc9a4dfc77798dd00348e82b90d393 (patch) | |
| tree | 1b35d64c490e8b9d5735d0949e452826c0ea971c /scripts/docgen.lua | |
| parent | [docgen] Update README.md (diff) | |
| download | nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar.gz nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar.bz2 nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar.lz nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar.xz nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.tar.zst nvim-lspconfig-43c7040614dc9a4dfc77798dd00348e82b90d393.zip | |
Refactor docgen and add package.json support (#29)
Diffstat (limited to 'scripts/docgen.lua')
| -rw-r--r-- | scripts/docgen.lua | 272 |
1 files changed, 170 insertions, 102 deletions
diff --git a/scripts/docgen.lua b/scripts/docgen.lua index a430e70b..d13dd14d 100644 --- a/scripts/docgen.lua +++ b/scripts/docgen.lua @@ -1,34 +1,10 @@ require 'nvim_lsp' local skeleton = require 'nvim_lsp/skeleton' +local util = require 'nvim_lsp/util' local inspect = vim.inspect - -local function filter(...) - local lines = {} - for i = 1, select("#", ...) do - local v = select(i, ...) - if v then - table.insert(lines, v) - end - end - return lines -end - -local function nilifempty(s) - if #s == 0 then return end - return s -end - -local function dedent(s) - local lines = vim.split(s, '\n', true) - if #lines == 0 then - return "" - end - local indent = #lines[1]:match("^%s*") - for i = 1, #lines do - lines[i] = lines[i]:sub(indent) - end - return table.concat(lines, '\n') -end +local uv = vim.loop +local fn = vim.fn +local tbl_flatten = vim.tbl_flatten local function template(s, params) return (s:gsub("{{([^{}]+)}}", params)) @@ -36,82 +12,58 @@ end local function map_list(t, fn) local res = {} - for i, v in ipairs(t) do table.insert(res, fn(v, i)) end + for i, v in ipairs(t) do + local x = fn(v, i) + if x ~= nil then + table.insert(res, x) + end + end return res end local function indent(n, s) - if n <= 0 then return s end + local prefix + if type(n) == 'number' then + if n <= 0 then return s end + prefix = string.rep(" ", n) + else + assert(type(n) == 'string', 'n must be number or string') + prefix = n + end local lines = vim.split(s, '\n', true) for i, line in ipairs(lines) do - lines[i] = string.rep(" ", n)..line + lines[i] = prefix..line end return table.concat(lines, '\n') end -local skeleton_keys = vim.tbl_keys(skeleton) -table.sort(skeleton_keys) +local function make_parts(fns) + return tbl_flatten(map_list(fns, function(v) + if type(v) == 'function' then + v = v() + end + return {v} + end)) +end -local function make_lsp_sections() - local sections = map_list(skeleton_keys, function(k) - local v = skeleton[k] - local tconf = v.template_config +local function make_section(indentlvl, sep, parts) + return indent(indentlvl, table.concat(make_parts(parts), sep)) +end - local params = {} - params.template_name = k - if tconf.commands then - local lines = {"Commands:"} - local cnames = vim.tbl_keys(tconf.commands) - table.sort(cnames) - for _, cname in ipairs(cnames) do - local def = tconf.commands[cname] - if def.description then - table.insert(lines, string.format("- %s: %s", cname, def.description)) - else - table.insert(lines, string.format("- %s", cname)) - end - lines[#lines] = indent(0, lines[#lines]) - end - params.commands = indent(0, table.concat(lines, '\n')) - end - if tconf.default_config then - local lines = {} - lines = {"Default Values:"} - local keys = vim.tbl_keys(tconf.default_config) - table.sort(keys) - for _, dk in ipairs(keys) do - local dv = tconf.default_config[dk] - local description = tconf.docs and tconf.docs.default_config and tconf.docs.default_config[dk] - if description and type(description) ~= 'string' then - description = inspect(description) - end - table.insert(lines, indent(2, string.format("%s = %s", dk, description or inspect(dv)))) - end - params.default_config = indent(0, table.concat(lines, '\n')) - end - do - local body_lines = filter( - params.commands - , params.default_config - ) - params.body = indent(2, table.concat(body_lines, '\n\n')) - end - params.preamble = "" - if tconf.docs then - local installation_instructions - if v.install then - installation_instructions = string.format("Can be installed in neovim with `:LspInstall %s`", k) - end - local preamble_parts = filter( - nilifempty(tconf.docs.description) - , installation_instructions - ) - -- Insert a newline after the preamble if it exists. - if #preamble_parts > 0 then table.insert(preamble_parts, '') end - params.preamble = table.concat(preamble_parts, '\n') - end +local function readfile(path) + assert(util.path.is_file(path)) + return io.open(path):read("*a") +end + +local function sorted_map_table(t, fn) + local keys = vim.tbl_keys(t) + table.sort(keys) + return map_list(keys, function(k) + return fn(k, t[k]) + end) +end - return template([[ +local lsp_section_template = [[ ## {{template_name}} {{preamble}} @@ -121,24 +73,140 @@ nvim_lsp#setup("{{template_name}}", {config}) {{body}} ``` -]], params) - end) - return table.concat(sections, '\n') +]] + +local function make_lsp_sections() + return make_section(0, '\n', sorted_map_table(skeleton, function(template_name, template_object) + local template_def = template_object.template_config + local docs = template_def.docs + + local params = { + template_name = template_name; + preamble = ""; + body = ""; + } + + params.body = make_section(2, '\n\n', { + function() + if not template_def.commands then return end + return make_section(0, '\n', { + "Commands:"; + sorted_map_table(template_def.commands, function(name, def) + if def.description then + return string.format("- %s: %s", name, def.description) + end + return string.format("- %s", name) + end) + }) + end; + function() + if not template_def.default_config then return end + return make_section(0, '\n', { + "Default Values:"; + sorted_map_table(template_def.default_config, function(k, v) + local description = ((docs or {}).default_config or {})[k] + if description and type(description) ~= 'string' then + description = inspect(description) + end + return indent(2, string.format("%s = %s", k, description or inspect(v))) + end) + }) + end; + }) + + if docs then + local tempdir = os.getenv("PACKAGE_JSON_CACHEDIR") or uv.fs_mkdtemp("/tmp/nvim-lsp.XXXXXX") + if not util.path.is_dir(tempdir) then + fn.mkdir(tempdir) + end + local preamble_parts = make_parts { + function() + if docs.description and #docs.description > 0 then + return docs.description + end + end; + function() + if template_object.install then + return string.format("Can be installed in neovim with `:LspInstall %s`", template_name) + end + end; + function() + if docs.package_json then + local filename = util.path.join(tempdir, template_name..'.package.json') + if util.path.is_file(filename) then + os.execute(string.format("curl -L -o %q -z %q %q", filename, filename, docs.package_json)) + else + os.execute(string.format("curl -L -o %q %q", filename, docs.package_json)) + end + if not util.path.is_file(filename) then + print("Failed to download package.json for %q at %q", template_name, docs.package_json) + os.exit(1) + return + end + local data = fn.json_decode(readfile(filename)) + -- The entire autogenerated section. + return make_section(0, '\n', { + -- The default settings section + function() + local default_settings = (data.contributes or {}).configuration + if not default_settings.properties then return end + -- The outer section. + return make_section(0, '\n', { + '<details><summary>'..(default_settings.title or "Available settings:")..'</summary>'; + ''; + -- The list of properties. + make_section(0, '\n\n', sorted_map_table(default_settings.properties, function(k, v) + local function tick(s) return string.format("`%s`", s) end + local function pre(s) return string.format("<pre>%s</pre>", s) end + local function code(s) return string.format("<code>%s</code>", s) end + local function bold(s) return string.format("**%s**", s) end + return make_section(0, '\n', { + "- "..make_section(0, ': ', { + bold(tick(k)); + function() + if v.enum then + return tick("enum "..inspect(v.enum)) + end + if v.type then + return tick(table.concat(tbl_flatten{v.type}, '|')) + end + end; + }); + ''; + make_section(2, '\n', { + {v.description}; + }); + }) + end)); + ''; + '</details>'; + }) + end; + }) + end + end + } + -- Insert a newline after the preamble if it exists. + if #preamble_parts > 0 then table.insert(preamble_parts, '') end + params.preamble = table.concat(preamble_parts, '\n') + end + + return template(lsp_section_template, params) + end)) end local function make_implemented_servers_list() - local parts = map_list(skeleton_keys, function(k) - return template("- [{{server}}](https://github.com/neovim/nvim-lsp#{{server}})", {server=k}) - end) - return table.concat(parts, '\n') + return make_section(0, '\n', sorted_map_table(skeleton, function(k) + return template("- [{{server}}](#{{server}})", {server=k}) + end)) end -local function generate_readme(params) +local function generate_readme(template_file, params) vim.validate { lsp_server_details = {params.lsp_server_details, 's'}; implemented_servers_list = {params.implemented_servers_list, 's'}; } - local input_template = io.open("scripts/README_template.md"):read("*a") + local input_template = readfile(template_file) local readme_data = template(input_template, params) local writer = io.open("README.md", "w") @@ -146,9 +214,9 @@ local function generate_readme(params) writer:close() end -generate_readme { +generate_readme("scripts/README_template.md", { implemented_servers_list = make_implemented_servers_list(); lsp_server_details = make_lsp_sections(); -} +}) -- vim:et ts=2 sw=2 |
