aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOri Perry <48057913+oriori1703@users.noreply.github.com>2026-10-05 14:02:24 +0300
committerGitHub <noreply@github.com>2026-10-05 07:02:24 -0400
commit0f9e596d896c4260cd7f6a59e90b04713eb948db (patch)
tree8c6a98b4869c456ec99861e76fbe2239690b0876
parentdocs: update configs.md (diff)
downloadnvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar.gz
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar.bz2
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar.lz
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar.xz
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.tar.zst
nvim-lspconfig-0f9e596d896c4260cd7f6a59e90b04713eb948db.zip
build(gen): type annotations for emmylua_ls #4534
-rw-r--r--lua/lspconfig/types/lsp/emmylua_ls.lua681
-rw-r--r--scripts/gen_annotations.lua30
-rw-r--r--scripts/gen_json_schemas.lua81
3 files changed, 779 insertions, 13 deletions
diff --git a/lua/lspconfig/types/lsp/emmylua_ls.lua b/lua/lspconfig/types/lsp/emmylua_ls.lua
new file mode 100644
index 00000000..332d682b
--- /dev/null
+++ b/lua/lspconfig/types/lsp/emmylua_ls.lua
@@ -0,0 +1,681 @@
+---@meta
+
+---```lua
+---default = {}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.CodeAction
+---Add space after `---` comments when inserting `@diagnostic disable-next-line`.
+---
+---When omitted, this follows the formatter's resolved
+---`emmy_doc.space_between_tag_columns` setting.
+---@field insertSpace? boolean
+
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.CodeLens
+---Enable code lens.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+
+---Configuration for EmmyLua code completion.
+---
+---```lua
+---default = {
+--- autoRequire = true,
+--- autoRequireFunction = "require",
+--- autoRequireNamingConvention = "keep",
+--- autoRequireSeparator = ".",
+--- baseFunctionIncludesName = true,
+--- callSnippet = false,
+--- enable = true,
+--- postfix = "@"
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Completion
+---Automatically insert call to `require` when autocompletion
+---inserts objects from other modules.
+---
+---```lua
+---default = true
+---```
+---@field autoRequire? boolean
+---The function used for auto-requiring modules.
+---
+---```lua
+---default = "require"
+---```
+---@field autoRequireFunction? string
+---The naming convention for auto-required filenames.
+---
+---```lua
+---default = "keep"
+---```
+---@field autoRequireNamingConvention? "keep"|"snake-case"|"pascal-case"|"camel-case"|"keep-class"
+---A separator used in auto-require paths.
+---
+---```lua
+---default = "."
+---```
+---@field autoRequireSeparator? string
+---Whether to include the name in the base function completion. Effect: `function () end` -> `function name() end`.
+---
+---```lua
+---default = true
+---```
+---@field baseFunctionIncludesName? boolean
+---Whether to use call snippets in completions.
+---@field callSnippet? boolean
+---Enable autocompletion.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+---Symbol that's used to trigger postfix autocompletion.
+---
+---```lua
+---default = "@"
+---```
+---@field postfix? string
+
+---Represents the diagnostic configuration for Emmyrc.
+---
+---```lua
+---default = {
+--- diagnosticInterval = 500,
+--- disable = {},
+--- enable = true,
+--- enables = {},
+--- globals = {},
+--- globalsRegex = {},
+--- severity = vim.empty_dict()
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Diagnostics
+---Delay between opening/changing a file and scanning it for errors, in milliseconds.
+---@field diagnosticInterval? integer
+---A list of diagnostic codes that are disabled.
+---
+---```lua
+---default = {}
+---```
+---@field disable? ("none"|"syntax-error"|"doc-syntax-error"|"type-not-found"|"missing-return"|"param-type-mismatch"|"missing-parameter"|"redundant-parameter"|"unreachable-code"|"unused"|"undefined-global"|"deprecated"|"access-invisible"|"discard-returns"|"undefined-field"|"local-const-reassign"|"iter-variable-reassign"|"duplicate-type"|"redefined-local"|"redefined-label"|"code-style-check"|"need-check-nil"|"await-in-sync"|"annotation-usage-error"|"return-type-mismatch"|"missing-return-value"|"redundant-return-value"|"undefined-doc-param"|"duplicate-doc-field"|"unknown-doc-tag"|"missing-fields"|"inject-field"|"circle-doc-class"|"incomplete-signature-doc"|"missing-global-doc"|"assign-type-mismatch"|"duplicate-require"|"non-literal-expressions-in-assert"|"unbalanced-assignments"|"unnecessary-assert"|"unnecessary-if"|"duplicate-set-field"|"duplicate-index"|"generic-constraint-mismatch"|"cast-type-mismatch"|"unresolved-require"|"require-module-not-visible"|"enum-value-mismatch"|"preferred-local-alias"|"read-only"|"global-in-non-module"|"attribute-param-type-mismatch"|"attribute-missing-parameter"|"attribute-redundant-parameter"|"invert-if"|"call-non-callable"|"inconsistent-type-access-modifier"|"missing-type-argument")[]
+---A flag indicating whether diagnostics are enabled.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+---A list of diagnostic codes that are enabled.
+---
+---```lua
+---default = {}
+---```
+---@field enables? ("none"|"syntax-error"|"doc-syntax-error"|"type-not-found"|"missing-return"|"param-type-mismatch"|"missing-parameter"|"redundant-parameter"|"unreachable-code"|"unused"|"undefined-global"|"deprecated"|"access-invisible"|"discard-returns"|"undefined-field"|"local-const-reassign"|"iter-variable-reassign"|"duplicate-type"|"redefined-local"|"redefined-label"|"code-style-check"|"need-check-nil"|"await-in-sync"|"annotation-usage-error"|"return-type-mismatch"|"missing-return-value"|"redundant-return-value"|"undefined-doc-param"|"duplicate-doc-field"|"unknown-doc-tag"|"missing-fields"|"inject-field"|"circle-doc-class"|"incomplete-signature-doc"|"missing-global-doc"|"assign-type-mismatch"|"duplicate-require"|"non-literal-expressions-in-assert"|"unbalanced-assignments"|"unnecessary-assert"|"unnecessary-if"|"duplicate-set-field"|"duplicate-index"|"generic-constraint-mismatch"|"cast-type-mismatch"|"unresolved-require"|"require-module-not-visible"|"enum-value-mismatch"|"preferred-local-alias"|"read-only"|"global-in-non-module"|"attribute-param-type-mismatch"|"attribute-missing-parameter"|"attribute-redundant-parameter"|"invert-if"|"call-non-callable"|"inconsistent-type-access-modifier"|"missing-type-argument")[]
+---A list of global variables.
+---
+---```lua
+---default = {}
+---```
+---@field globals? string[]
+---A list of regular expressions for global variables.
+---
+---```lua
+---default = {}
+---```
+---@field globalsRegex? string[]
+---A map of diagnostic codes to their severity settings.
+---
+---```lua
+---default = {}
+---```
+---@field severity? table
+
+---```lua
+---default = {
+--- knownTags = {},
+--- privateName = {},
+--- syntax = "md"
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Doc
+---List of known documentation tags.
+---
+---```lua
+---default = {}
+---```
+---@field knownTags? string[]
+---Treat specific field names as private, e.g. `m_*` means `XXX.m_id` and `XXX.m_type` are private, witch can only be accessed in the class where the definition is located.
+---
+---```lua
+---default = {}
+---```
+---@field privateName? string[]
+---When `syntax` is `Myst` or `Rst`, specifies default role used
+---with RST processor.
+---@field rstDefaultRole? string
+---When `syntax` is `Myst` or `Rst`, specifies primary domain used
+---with RST processor.
+---@field rstPrimaryDomain? string
+---Syntax for highlighting documentation.
+---
+---```lua
+---default = "md"
+---```
+---@field syntax? "none" | "md" | "myst" | "rst"
+
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.DocumentColor
+---Enable parsing strings for color tags and showing a color picker next to them.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+
+---```lua
+---default = {
+--- useDiff = false
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Format
+---Whether to enable external tool formatting.
+---@field externalTool? table
+---Whether to enable external tool range formatting.
+---@field externalToolRangeFormat? table
+---Whether to use the diff algorithm for formatting.
+---@field useDiff? boolean
+
+---```lua
+---default = {
+--- enable = true,
+--- enumParamHint = false,
+--- indexHint = true,
+--- localHint = true,
+--- metaCallHint = true,
+--- overrideHint = true,
+--- paramHint = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Hint
+---Enable inlay hints.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+---Show name of enumerator when passing a literal value to a function
+---that expects an enum.
+---
+---Example:
+---
+---```lua
+------ @enum Level
+---local Foo = {
+--- Info = 1,
+--- Error = 2,
+---}
+---
+------ @param l Level
+---function print_level(l) end
+---
+---print_level(1 --[[ Hint: Level.Info ]])
+---```
+---@field enumParamHint? boolean
+---Show named array indexes.
+---
+---Example:
+---
+---```lua
+---local array = {
+--- [1] = 1, -- [name]
+---}
+---
+---print(array[1] --[[ Hint: name ]])
+---```
+---
+---```lua
+---default = true
+---```
+---@field indexHint? boolean
+---Show types of local variables.
+---
+---```lua
+---default = true
+---```
+---@field localHint? boolean
+---Show hint when calling an object results in a call to
+---its meta table's `__call` function.
+---
+---```lua
+---default = true
+---```
+---@field metaCallHint? boolean
+---Show methods that override functions from base class.
+---
+---```lua
+---default = true
+---```
+---@field overrideHint? boolean
+---Show parameter names in function calls and parameter types in function definitions.
+---
+---```lua
+---default = true
+---```
+---@field paramHint? boolean
+
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Hover
+---The detail number of hover information.
+---Default is `None`, which means using the default detail level.
+---You can set it to a number between `1` and `255` to customize
+---@field customDetail? integer
+---Enable showing documentation on hover.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.InlineValues
+---Show inline values during debug.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+
+---```lua
+---default = {
+--- enable = true,
+--- fuzzySearch = true,
+--- shortStringSearch = false
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.References
+---Enable searching for symbol usages.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+---Use fuzzy search when searching for symbol usages
+---and normal search didn't find anything.
+---
+---```lua
+---default = true
+---```
+---@field fuzzySearch? boolean
+---Also search for usages in strings.
+---@field shortStringSearch? boolean
+
+---```lua
+---default = {
+--- paths = {}
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Resource
+---```lua
+---default = {}
+---```
+---@field paths? string[]
+
+---```lua
+---default = {
+--- extensions = {},
+--- frameworkVersions = {},
+--- nonstandardSymbol = {},
+--- requireLikeFunction = {},
+--- requirePattern = {},
+--- special = vim.empty_dict(),
+--- version = "LuaLatest"
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Runtime
+---file Extensions. eg: .lua, .lua.txt
+---
+---```lua
+---default = {}
+---```
+---@field extensions? string[]
+---Framework versions.
+---
+---```lua
+---default = {}
+---```
+---@field frameworkVersions? string[]
+---Non-standard symbols.
+---
+---```lua
+---default = {}
+---```
+---@field nonstandardSymbol? ("//" | "/**/" | "`" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "//=" | "|=" | "&=" | "<<=" | ">>=" | "||" | "&&" | "!" | "!=" | "continue")[]
+---Functions that like require.
+---
+---```lua
+---default = {}
+---```
+---@field requireLikeFunction? string[]
+---Require pattern. eg. "?.lua", "?/init.lua"
+---
+---```lua
+---default = {}
+---```
+---@field requirePattern? string[]
+---Special symbols.
+---
+---```lua
+---default = {}
+---```
+---@field special? table
+---Lua version.
+---
+---```lua
+---default = "LuaLatest"
+---```
+---@field version? "LuaJIT2" | "LuaJIT3"|"Lua5.1"|"LuaJIT"|"Lua5.2"|"Lua5.3"|"Lua5.4"|"Lua5.5"|"LuaLatest"
+
+---```lua
+---default = {
+--- enable = true,
+--- renderDocumentationMarkup = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.SemanticTokens
+---Enable semantic tokens.
+---
+---```lua
+---default = true
+---```
+---@field enable? boolean
+---Render Markdown/RST in documentation. Set `doc.syntax` for this option to have effect.
+---@field renderDocumentationMarkup? boolean
+
+---```lua
+---default = {
+--- detailSignatureHelper = true
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Signature
+---Whether to enable signature help.
+---
+---```lua
+---default = true
+---```
+---@field detailSignatureHelper? boolean
+
+---```lua
+---default = {
+--- arrayIndex = true,
+--- docBaseConstMatchBaseType = true,
+--- metaOverrideFileDefine = true,
+--- requirePath = false,
+--- typeCall = false
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Strict
+---Whether to enable strict mode array indexing.
+---
+---```lua
+---default = true
+---```
+---@field arrayIndex? boolean
+---Base constant types defined in doc can match base types, allowing int to match `---@alias id 1|2|3`, same for string.
+---@field docBaseConstMatchBaseType? boolean
+---meta define overrides file define
+---
+---```lua
+---default = true
+---```
+---@field metaOverrideFileDefine? boolean
+---Whether to enable strict mode require path.
+---@field requirePath? boolean
+---@field typeCall? boolean
+
+---```lua
+---default = {
+--- enableReindex = false,
+--- encoding = "utf-8",
+--- ignoreDir = {},
+--- ignoreGlobs = {},
+--- library = {},
+--- moduleMap = {},
+--- packages = {},
+--- preloadFileSize = 0,
+--- reindexDuration = 5000,
+--- workspaceRoots = {}
+---}
+---```
+---@class _.lspconfig.settings.emmylua_ls.Emmylua.Workspace
+---Enable full project reindex after changing a file.
+---@field enableReindex? boolean
+---Encoding. eg: "utf-8"
+---
+---```lua
+---default = "utf-8"
+---```
+---@field encoding? string
+---Ignore directories.
+---
+---```lua
+---default = {}
+---```
+---@field ignoreDir? string[]
+---Ignore globs. eg: ["**/*.lua"]
+---
+---```lua
+---default = {}
+---```
+---@field ignoreGlobs? string[]
+---Library paths. Can be a string path or an object with path and ignore rules.
+---eg: ["/usr/local/share/lua/5.1"] or [{"path": "/usr/local/share/lua/5.1", "ignoreDir": ["test"], "ignoreGlobs": ["**/*.spec.lua"]}]
+---
+---```lua
+---default = {}
+---```
+---@field library? (string|table)[]
+---Module map. key is regex, value is new module regex
+---eg: {
+--- "^(.*)$": "module_$1"
+--- "^lib(.*)$": "script$1"
+---}
+---
+---```lua
+---default = {}
+---```
+---@field moduleMap? table[]
+---Package directories. Can be a string path or an object with path and ignore rules.
+---Treat the parent directory as a `library`, but only add files from the specified directory.
+---eg: ["/usr/local/share/lua/5.1/module"] or [{"path": "/usr/local/share/lua/5.1/module", "ignoreDir": ["test"], "ignoreGlobs": ["**/*.spec.lua"]}]
+---
+---```lua
+---default = {}
+---```
+---@field packages? (string|table)[]
+---```lua
+---default = 0
+---```
+---@field preloadFileSize? integer
+---Delay between changing a file and full project reindex, in milliseconds.
+---
+---```lua
+---default = 5000
+---```
+---@field reindexDuration? integer
+---Workspace roots. eg: ["src", "test"]
+---
+---```lua
+---default = {}
+---```
+---@field workspaceRoots? string[]
+
+---@class _.lspconfig.settings.emmylua_ls.Emmylua
+---```lua
+---default = {}
+---```
+---@field codeAction? _.lspconfig.settings.emmylua_ls.Emmylua.CodeAction
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@field codeLens? _.lspconfig.settings.emmylua_ls.Emmylua.CodeLens
+---Configuration for EmmyLua code completion.
+---
+---```lua
+---default = {
+--- autoRequire = true,
+--- autoRequireFunction = "require",
+--- autoRequireNamingConvention = "keep",
+--- autoRequireSeparator = ".",
+--- baseFunctionIncludesName = true,
+--- callSnippet = false,
+--- enable = true,
+--- postfix = "@"
+---}
+---```
+---@field completion? _.lspconfig.settings.emmylua_ls.Emmylua.Completion
+---Represents the diagnostic configuration for Emmyrc.
+---
+---```lua
+---default = {
+--- diagnosticInterval = 500,
+--- disable = {},
+--- enable = true,
+--- enables = {},
+--- globals = {},
+--- globalsRegex = {},
+--- severity = vim.empty_dict()
+---}
+---```
+---@field diagnostics? _.lspconfig.settings.emmylua_ls.Emmylua.Diagnostics
+---```lua
+---default = {
+--- knownTags = {},
+--- privateName = {},
+--- syntax = "md"
+---}
+---```
+---@field doc? _.lspconfig.settings.emmylua_ls.Emmylua.Doc
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@field documentColor? _.lspconfig.settings.emmylua_ls.Emmylua.DocumentColor
+---```lua
+---default = {
+--- useDiff = false
+---}
+---```
+---@field format? _.lspconfig.settings.emmylua_ls.Emmylua.Format
+---```lua
+---default = {
+--- enable = true,
+--- enumParamHint = false,
+--- indexHint = true,
+--- localHint = true,
+--- metaCallHint = true,
+--- overrideHint = true,
+--- paramHint = true
+---}
+---```
+---@field hint? _.lspconfig.settings.emmylua_ls.Emmylua.Hint
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@field hover? _.lspconfig.settings.emmylua_ls.Emmylua.Hover
+---```lua
+---default = {
+--- enable = true
+---}
+---```
+---@field inlineValues? _.lspconfig.settings.emmylua_ls.Emmylua.InlineValues
+---```lua
+---default = {
+--- enable = true,
+--- fuzzySearch = true,
+--- shortStringSearch = false
+---}
+---```
+---@field references? _.lspconfig.settings.emmylua_ls.Emmylua.References
+---```lua
+---default = {
+--- paths = {}
+---}
+---```
+---@field resource? _.lspconfig.settings.emmylua_ls.Emmylua.Resource
+---```lua
+---default = {
+--- extensions = {},
+--- frameworkVersions = {},
+--- nonstandardSymbol = {},
+--- requireLikeFunction = {},
+--- requirePattern = {},
+--- special = vim.empty_dict(),
+--- version = "LuaLatest"
+---}
+---```
+---@field runtime? _.lspconfig.settings.emmylua_ls.Emmylua.Runtime
+---```lua
+---default = {
+--- enable = true,
+--- renderDocumentationMarkup = true
+---}
+---```
+---@field semanticTokens? _.lspconfig.settings.emmylua_ls.Emmylua.SemanticTokens
+---```lua
+---default = {
+--- detailSignatureHelper = true
+---}
+---```
+---@field signature? _.lspconfig.settings.emmylua_ls.Emmylua.Signature
+---```lua
+---default = {
+--- arrayIndex = true,
+--- docBaseConstMatchBaseType = true,
+--- metaOverrideFileDefine = true,
+--- requirePath = false,
+--- typeCall = false
+---}
+---```
+---@field strict? _.lspconfig.settings.emmylua_ls.Emmylua.Strict
+---```lua
+---default = {
+--- enableReindex = false,
+--- encoding = "utf-8",
+--- ignoreDir = {},
+--- ignoreGlobs = {},
+--- library = {},
+--- moduleMap = {},
+--- packages = {},
+--- preloadFileSize = 0,
+--- reindexDuration = 5000,
+--- workspaceRoots = {}
+---}
+---```
+---@field workspace? _.lspconfig.settings.emmylua_ls.Emmylua.Workspace
+
+---@class lspconfig.settings.emmylua_ls
+---@field emmylua? _.lspconfig.settings.emmylua_ls.Emmylua
diff --git a/scripts/gen_annotations.lua b/scripts/gen_annotations.lua
index 1612d82b..1ca3d100 100644
--- a/scripts/gen_annotations.lua
+++ b/scripts/gen_annotations.lua
@@ -255,25 +255,33 @@ local function lua_type_for(prop)
' | '
)
end
+ if prop.const ~= nil then
+ return vim.inspect(prop.const)
+ end
local types = type(prop.type) == 'table' and prop.type or { prop.type }
- if vim.tbl_isempty(types) and type(prop.anyOf) == 'table' then
- return table.concat(
- vim.tbl_map(function(p)
- return lua_type_for(p)
- end, prop.anyOf),
- '|'
- )
+ -- Convert `anyOf`/`oneOf` to a union, excluding null:
+ -- `{ anyOf = { { type = 'string' }, { type = 'number' }, { type = 'null' } } }` => `string|number`.
+ local alternatives = prop.anyOf or prop.oneOf
+ if vim.tbl_isempty(types) and type(alternatives) == 'table' then
+ local alternative_types = {}
+ for _, alternative in ipairs(alternatives) do
+ if alternative.type ~= 'null' then
+ table.insert(alternative_types, lua_type_for(alternative))
+ end
+ end
+ return #alternative_types > 0 and table.concat(alternative_types, '|') or 'any'
end
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
- return 'any[]'
+ if type(prop.items) == 'table' then
+ local item_type = lua_type_for(prop.items)
+ if item_type:find('|', 1, true) then
+ item_type = '(' .. item_type .. ')'
end
- return (prop.items.type == 'object' and 'table' or prop.items.type) .. '[]'
+ return item_type .. '[]'
end
return 'any[]'
end
diff --git a/scripts/gen_json_schemas.lua b/scripts/gen_json_schemas.lua
index 3d6f2999..c1a9b109 100644
--- a/scripts/gen_json_schemas.lua
+++ b/scripts/gen_json_schemas.lua
@@ -13,6 +13,7 @@ local index = {
denols = 'https://raw.githubusercontent.com/denoland/vscode_deno/main/package.json',
elixirls = 'https://raw.githubusercontent.com/elixir-lsp/vscode-elixir-ls/master/package.json',
elmls = 'https://raw.githubusercontent.com/elm-tooling/elm-language-client-vscode/master/package.json',
+ emmylua_ls = 'https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/main/crates/emmylua_code_analysis/resources/schema.json',
eslint = 'https://raw.githubusercontent.com/microsoft/vscode-eslint/main/package.json',
flow = 'https://raw.githubusercontent.com/flowtype/flow-for-vscode/master/package.json',
fsautocomplete = 'https://raw.githubusercontent.com/ionide/ionide-vscode-fsharp/main/release/package.json',
@@ -132,6 +133,9 @@ local overrides = {
cssls = {
translate = true,
},
+ emmylua_ls = {
+ prefix = 'emmylua.',
+ },
nixd = {
prefix = 'nixd.',
},
@@ -156,6 +160,73 @@ local function resolve_schema_configs()
return vim.tbl_deep_extend('force', schemas, overrides)
end
+---Resolve local JSON pointer references in a schema node.
+---For root `{"$defs":{"port":{"type":"integer"}}}`, `{"$ref":"#/$defs/port"}` => `{"type":"integer"}`.
+---`#` => `root`; `#/items/0` => `root.items[1]`.
+---`#/foo//bar` => `root.foo[''].bar`; `#/%24defs/port` => `root['$defs'].port`.
+---@param node any
+---@param root table
+---@param resolving? table<string, true>
+---@return any
+local function resolve_local_refs(node, root, resolving)
+ if type(node) ~= 'table' then
+ return node
+ end
+
+ local ref = node['$ref']
+ local pointer
+ if type(ref) == 'string' and vim.startswith(ref, '#') then
+ pointer = vim.uri_decode(ref:sub(2))
+ end
+ if pointer == nil or (pointer ~= '' and not vim.startswith(pointer, '/')) then
+ for key, value in pairs(node) do
+ node[key] = resolve_local_refs(value, root, resolving)
+ end
+ return node
+ end
+
+ resolving = resolving or {}
+ if resolving[ref] then
+ error('Cyclic schema reference: ' .. ref)
+ end
+
+ local target = root
+ -- `#/$defs/foo~1bar~0baz` resolves to `root['$defs']['foo/bar~baz']` (`~1` escapes `/`, `~0` escapes `~`).
+ for part in pointer:gmatch('/([^/]*)') do
+ local token = part:gsub('~1', '/'):gsub('~0', '~')
+ ---@type string|integer
+ local key = token
+ if type(target) ~= 'table' then
+ error('Could not resolve schema reference: ' .. ref)
+ end
+ if vim.islist(target) then
+ if token ~= '0' and not token:match('^[1-9]%d*$') then
+ error('Could not resolve schema reference: ' .. ref)
+ end
+ key = assert(tonumber(token)) + 1
+ end
+ if target[key] == nil then
+ error('Could not resolve schema reference: ' .. ref)
+ end
+ target = target[key]
+ end
+
+ resolving[ref] = true
+ local resolved = resolve_local_refs(vim.deepcopy(target), root, resolving)
+ resolving[ref] = nil
+ for key, value in pairs(node) do
+ if key ~= '$ref' then
+ if type(resolved) ~= 'table' or resolved[key] ~= nil then
+ -- TODO: Preserve conflicting constraints with `allOf` once annotation generation supports it.
+ -- See https://json-schema.org/draft/2020-12/json-schema-core#section-8.2.3.1.
+ error(('Cannot merge schema reference sibling %q: %s'):format(key, ref))
+ end
+ resolved[key] = resolve_local_refs(value, root, resolving)
+ end
+ end
+ return resolved
+end
+
---Replaces localized documentation placeholders in a schema tree in place.
---
---This is used for schemas whose documentation strings are stored in a
@@ -218,12 +289,18 @@ local function generate_server_schema(schema)
for _, config_section in pairs(config_schema) do
if config_section.properties then
for k, v in pairs(config_section.properties) do
- properties[k] = v
+ if k ~= '$schema' then
+ properties[k] = resolve_local_refs(v, config_section)
+ end
end
end
end
elseif config_schema.properties then
- properties = config_schema.properties
+ for k, v in pairs(config_schema.properties) do
+ if k ~= '$schema' then
+ properties[k] = resolve_local_refs(v, config_schema)
+ end
+ end
end
-- `properties["enable_snippets"]` => `properties["zls.enable_snippets"]`