diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..df093d80c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,50 @@ +name: Rust + +on: + push: + branches: + - docs-v2 + tags: + - "*" + +jobs: + build_docs: + name: Build docs + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install requirements + run: | + python -m pip install --upgrade pip + python -m pip install -r docs/v2/requirements.txt + - name: Build docs + run: | + cd docs/v2 + make html-all + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: html_output + path: docs/v2/build/html + include-hidden-files: true + + publish_docs: + name: Publish docs to GitHub Pages + needs: + - build_docs + permissions: write-all + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: html_output + path: docs/v2/build/html + - name: Publish HTML + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: docs/v2/build/html + target-folder: . diff --git a/.python-version b/.python-version new file mode 100644 index 000000000..615881643 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +emmylua-docs diff --git a/.vscode/settings.json b/.vscode/settings.json index c052c5941..b5b45b093 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,7 @@ "files.insertFinalNewline": true, "files.trimFinalNewlines": true, "files.trimTrailingWhitespace": true, - "files.trimTrailingWhitespaceInRegexAndStrings": true + "files.trimTrailingWhitespaceInRegexAndStrings": true, + "python-envs.defaultEnvManager": "ms-python.python:system", + "python-envs.pythonProjects": [] } diff --git a/crates/emmylua_code_analysis/resources/schema.json b/crates/emmylua_code_analysis/resources/schema.json index abc801a02..40ca8bda1 100644 --- a/crates/emmylua_code_analysis/resources/schema.json +++ b/crates/emmylua_code_analysis/resources/schema.json @@ -10,18 +10,21 @@ ] }, "codeAction": { + "description": "Configuration for code actions and quick fixes.", "$ref": "#/$defs/EmmyrcCodeAction", "default": { "insertSpace": false } }, "codeLens": { + "description": "Configuration for code lens features.", "$ref": "#/$defs/EmmyrcCodeLens", "default": { "enable": true } }, "completion": { + "description": "Configuration for code completion features.", "$ref": "#/$defs/EmmyrcCompletion", "default": { "autoRequire": true, @@ -35,6 +38,7 @@ } }, "diagnostics": { + "description": "Configuration for diagnostics and error detection.", "$ref": "#/$defs/EmmyrcDiagnostic", "default": { "diagnosticInterval": 500, @@ -47,6 +51,7 @@ } }, "doc": { + "description": "Configuration for documentation parsing.", "$ref": "#/$defs/EmmyrcDoc", "default": { "knownTags": [], @@ -55,12 +60,14 @@ } }, "documentColor": { + "description": "Configuration for document color features.", "$ref": "#/$defs/EmmyrcDocumentColor", "default": { "enable": true } }, "format": { + "description": "Configuration for code formatting.", "$ref": "#/$defs/EmmyrcReformat", "default": { "externalTool": null, @@ -68,6 +75,7 @@ } }, "hint": { + "description": "Configuration for inlay hints in the editor.", "$ref": "#/$defs/EmmyrcInlayHint", "default": { "enable": true, @@ -80,18 +88,21 @@ } }, "hover": { + "description": "Configuration for hover information.", "$ref": "#/$defs/EmmyrcHover", "default": { "enable": true } }, "inlineValues": { + "description": "Configuration for inline value display.", "$ref": "#/$defs/EmmyrcInlineValues", "default": { "enable": true } }, "references": { + "description": "Configuration for reference lookup features.", "$ref": "#/$defs/EmmyrcReference", "default": { "enable": true, @@ -100,12 +111,14 @@ } }, "resource": { + "description": "Configuration for resource file management.", "$ref": "#/$defs/EmmyrcResource", "default": { "paths": [] } }, "runtime": { + "description": "Configuration for Lua runtime.", "$ref": "#/$defs/EmmyrcRuntime", "default": { "classDefaultCall": { @@ -122,6 +135,7 @@ } }, "semanticTokens": { + "description": "Configuration for semantic token highlighting.", "$ref": "#/$defs/EmmyrcSemanticToken", "default": { "enable": true, @@ -129,12 +143,14 @@ } }, "signature": { + "description": "Configuration for function signature help.", "$ref": "#/$defs/EmmyrcSignature", "default": { "detailSignatureHelper": true } }, "strict": { + "description": "Configuration for strict type checks.", "$ref": "#/$defs/EmmyrcStrict", "default": { "arrayIndex": true, @@ -145,6 +161,7 @@ } }, "workspace": { + "description": "Configuration for workspace management.", "$ref": "#/$defs/EmmyrcWorkspace", "default": { "enableReindex": false, @@ -164,17 +181,17 @@ "type": "object", "properties": { "forceNonColon": { - "description": "Mandatory non`:` definition. When `function_name` is not empty, it takes effect.", + "description": "Remove the `self` parameter from list of constructor parameters\nwhen inferring constructor signature using `functionName`.", "type": "boolean", "default": true }, "forceReturnSelf": { - "description": "Force to return `self`.", + "description": "Always use `self` as constructor's return type when inferring\nconstructor signature using `functionName`.", "type": "boolean", "default": true }, "functionName": { - "description": "class default overload function. eg. \"__init\".", + "description": "Name of the method that's used to resolve class default `__call` operator.\n\nFor example, if `functionName` is `\"__init\"`, then EmmyLua will use parameters\nand return types of `__init` method as parameters and return types\nof class' `__call` operator:\n\n```lua\n--- @class Example\n--- @field __init fun(): Example\n\n-- Unless `Example` provides its own `@overload`,\n-- any call to `Example()` is treated as a call to `Example:__init()`:\nlocal example = Example()\n-- ^^^^^^^ type of `example` is inferred as `Example`.\n```", "type": "string", "default": "" } @@ -445,12 +462,28 @@ ] }, "DocSyntax": { - "type": "string", - "enum": [ - "none", - "md", - "myst", - "rst" + "description": "Syntax for highlighting documentation.", + "oneOf": [ + { + "description": "Documentation is not highlighted.", + "type": "string", + "const": "none" + }, + { + "description": "Documentation is highlighted as plain [MarkDown].\n\n[MarkDown]: https://commonmark.org/", + "type": "string", + "const": "md" + }, + { + "description": "Documentation is highlighted as [MySt], a MarkDown plugin for [Sphinx].\n\nEnables Autocompletion and Go To Definition for sphinx cross-references.\n\n[MySt]: https://myst-parser.readthedocs.io/\n[Sphinx]: https://www.sphinx-doc.org/", + "type": "string", + "const": "myst" + }, + { + "description": "Documentation is highlighted as [ReStructured Text].\n\nEnables Autocompletion and Go To Definition for [sphinx] cross-references.\n\n[ReStructured Text]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html\n[sphinx]: https://www.sphinx-doc.org/", + "type": "string", + "const": "rst" + } ] }, "EmmyrcCodeAction": { @@ -459,8 +492,7 @@ "insertSpace": { "description": "Add space after `---` comments when inserting `@diagnostic disable-next-line`.", "type": "boolean", - "default": false, - "x-vscode-setting": true + "default": false } } }, @@ -476,40 +508,40 @@ } }, "EmmyrcCompletion": { - "description": "Configuration for EmmyLua code completion.", "type": "object", "properties": { "autoRequire": { - "description": "Automatically insert call to `require` when autocompletion\ninserts objects from other modules.", + "description": "When enabled, selecting a completion suggestion from another\nmodule will add the appropriate require statement.", "type": "boolean", "default": true, "x-vscode-setting": true }, "autoRequireFunction": { - "description": "The function used for auto-requiring modules.", + "description": "Name of the function that's inserted when auto-requiring modules.\n\nDefault is `\"require\"`, but can be customized to use any module loader function.", "type": "string", "default": "require" }, "autoRequireNamingConvention": { - "description": "The naming convention for auto-required filenames.", + "description": "The naming convention for auto-required filenames.\n\nControls how the imported module names are formatted in the `require` statement.", "$ref": "#/$defs/EmmyrcFilenameConvention", "default": "keep" }, "autoRequireSeparator": { - "description": "A separator used in auto-require paths.", + "description": "Defines the character used to separate path segments in require statements.\n\nDefault is `\".\"`, but can be changed to other separators like `\"/\"`.", "type": "string", "default": "." }, "baseFunctionIncludesName": { - "description": "Whether to include the name in the base function completion. Effect: `function () end` -> `function name() end`.", + "description": "Whether to include the name in the base function in postfix autocompletion.\n\nEffect: `function () end` -> `function name() end`.", "type": "boolean", "default": true, "x-vscode-setting": true }, "callSnippet": { - "description": "Whether to use call snippets in completions.", + "description": "Whether to use call snippets in completions.\n\nWhen enabled, function completions will insert a snippet with placeholders\nfor function arguments, allowing for quick tabbing between parameters.", "type": "boolean", - "default": false + "default": false, + "x-vscode-setting": true }, "enable": { "description": "Enable autocompletion.", @@ -558,7 +590,7 @@ "x-vscode-setting": true }, "disable": { - "description": "A list of diagnostic codes that are disabled.", + "description": "A list of suppressed diagnostics.", "type": "array", "default": [], "items": { @@ -566,12 +598,12 @@ } }, "enable": { - "description": "A flag indicating whether diagnostics are enabled.", + "description": "A flag indicating whether diagnostics are enabled at all.", "type": "boolean", "default": true }, "enables": { - "description": "A list of diagnostic codes that are enabled.", + "description": "A list of diagnostic codes that are enabled, in addition to default ones.", "type": "array", "default": [], "items": { @@ -579,7 +611,7 @@ } }, "globals": { - "description": "A list of global variables.", + "description": "A list of global variables.\n\nVariables from this list are always treated as defined globals.", "type": "array", "default": [], "items": { @@ -587,7 +619,7 @@ } }, "globalsRegex": { - "description": "A list of regular expressions for global variables.", + "description": "A list of regular expressions for global variables.\n\nVariables that match these regular expressions are always treated as defined globals.", "type": "array", "default": [], "items": { @@ -616,7 +648,7 @@ } }, "privateName": { - "description": "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.", + "description": "List of glob patterns that enable treating specific field names as private.\n\nFor example, `m_*` would make fields `Type.m_id` and `Type.m_type` private.", "type": "array", "default": [], "items": { @@ -624,14 +656,14 @@ } }, "rstDefaultRole": { - "description": "When `syntax` is `Myst` or `Rst`, specifies default role used\nwith RST processor.", + "description": "When `syntax` is `Myst` or `Rst`, specifies [default role] used\nwith RST processor.\n\n[default role]: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-default_role", "type": [ "string", "null" ] }, "rstPrimaryDomain": { - "description": "When `syntax` is `Myst` or `Rst`, specifies primary domain used\nwith RST processor.", + "description": "When `syntax` is `Myst` or `Rst`, specifies [primary domain] used\nwith RST processor.\n\n[primary domain]: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-primary_domain", "type": [ "string", "null" @@ -659,7 +691,7 @@ "type": "object", "properties": { "args": { - "description": "The arguments to pass to the external tool.", + "description": "List of arguments to pass to the external tool.\n\nEach argument can contain the following patterns:\n\n- `${file}` expands to the file path that needs formatting;\n\n- `${indent_size}` expands to numeric value for indentation size;\n\n- `${use_tabs?:}` expands to `` placeholder or\n `` placeholder depending on whether tabs are used\n for indentation.\n\n For example, `${use_tabs?--tabs}` will expand to `--tabs` if tabs\n are required, or an empty string if tabs are not required.\n\n- `${insert_final_newline?:}` expands to ``\n placeholder or `` placeholder depending on whether the tool\n should insert final newline.\n\n- `${non_standard_symbol?:}` expands to ``\n placeholder or `` placeholder depending on whether\n non-standard symbols are enabled.", "type": "array", "default": [], "items": { @@ -672,6 +704,7 @@ "default": "" }, "timeout": { + "description": "Command timeout, in milliseconds.", "type": "integer", "format": "uint64", "default": 5000, @@ -680,29 +713,30 @@ } }, "EmmyrcFilenameConvention": { + "description": "The naming convention for auto-required filenames.\n\nControls how the imported module names are formatted in the `require` statement.", "oneOf": [ { - "description": "Keep the original filename.", + "description": "Keep the original filename without any transformation.\n\nExample: `\"my-module\"` remains `\"my-module\"`.", "type": "string", "const": "keep" }, { - "description": "Convert the filename to snake_case.", + "description": "Convert the filename to `snake_case`.\n\nExample: `\"MyModule\"` becomes `\"my_module\"`.", "type": "string", "const": "snake-case" }, { - "description": "Convert the filename to PascalCase.", + "description": "Convert the filename to `PascalCase`.\n\nExample: `\"my_module\"` becomes `\"MyModule\"`.", "type": "string", "const": "pascal-case" }, { - "description": "Convert the filename to camelCase.", + "description": "Convert the filename to `camelCase`.\n\nExample: `\"my_module\"` becomes `\"myModule\"`.", "type": "string", "const": "camel-case" }, { - "description": "When returning class definition, use class name, otherwise keep original name.", + "description": "When returning a class definition, use the class name; otherwise keep the original name.\n\nThis is useful for modules that export a single class with a name that might differ from the filename.", "type": "string", "const": "keep-class" } @@ -810,7 +844,7 @@ "const": "Lua5.5" }, { - "description": "Lua Latest", + "description": "Lua Latest, currently set to `Lua5.4`.", "type": "string", "const": "LuaLatest" } @@ -867,7 +901,7 @@ "type": "object", "properties": { "externalTool": { - "description": "Whether to enable internal code reformatting.", + "description": "Configuration for external formatting tool.", "anyOf": [ { "$ref": "#/$defs/EmmyrcExternalTool" @@ -889,6 +923,7 @@ "type": "object", "properties": { "paths": { + "description": "List of resource directories used in a project. Files from these\ndirectories will be added to autocompletion when completing\nfile paths.\n\nThis list can contain anything, like directories with game assets,\ntemplate files, and so on. No special interpretation beyond\nautocompletion is given to these paths.", "type": "array", "default": [], "items": { @@ -901,7 +936,7 @@ "type": "object", "properties": { "classDefaultCall": { - "description": "class default overload function.", + "description": "Controls resolution of class constructors.", "$ref": "#/$defs/ClassDefaultCall", "default": { "forceNonColon": false, @@ -910,7 +945,7 @@ } }, "extensions": { - "description": "file Extensions. eg: .lua, .lua.txt", + "description": "Extensions of Lua files that need analysis.\n\nExample: `[\".lua\", \".lua.txt\"]`.", "type": "array", "default": [], "items": { @@ -918,7 +953,6 @@ } }, "frameworkVersions": { - "description": "Framework versions.", "type": "array", "default": [], "items": { @@ -926,7 +960,7 @@ } }, "nonstandardSymbol": { - "description": "Non-standard symbols.", + "description": "List of enabled non-standard symbols.", "type": "array", "default": [], "items": { @@ -934,7 +968,7 @@ } }, "requireLikeFunction": { - "description": "Functions that like require.", + "description": "Functions that are treated like `require`.", "type": "array", "default": [], "items": { @@ -942,7 +976,7 @@ } }, "requirePattern": { - "description": "Require pattern. eg. \"?.lua\", \"?/init.lua\"", + "description": "Require pattern in the format of Lua's [`path`].\n\nExample: `[\"?.lua\", \"?/init.lua\"]`.\n\n[`path`]: https://www.lua.org/pil/8.1.html", "type": "array", "default": [], "items": { @@ -979,7 +1013,8 @@ "detailSignatureHelper": { "description": "Whether to enable signature help.", "type": "boolean", - "default": true + "default": true, + "x-vscode-setting": true } } }, @@ -987,22 +1022,22 @@ "type": "object", "properties": { "arrayIndex": { - "description": "Whether to enable strict mode array indexing.", + "description": "Whether to enable strict mode when inferring type\nof array indexing operation.", "type": "boolean", "default": true }, "docBaseConstMatchBaseType": { - "description": "Base constant types defined in doc can match base types, allowing int to match `---@alias id 1|2|3`, same for string.", + "description": "Base constant types defined in doc can match base types, allowing `int`\nto match `---@alias id 1|2|3`, same for string.", "type": "boolean", "default": false }, "metaOverrideFileDefine": { - "description": "meta define overrides file define", + "description": "Definitions from `@meta` files always overrides definitions\nfrom normal files.", "type": "boolean", "default": true }, "requirePath": { - "description": "Whether to enable strict mode require path.", + "description": "Whether to enable strict mode for resolving require paths.", "type": "boolean", "default": false }, @@ -1022,12 +1057,12 @@ "x-vscode-setting": true }, "encoding": { - "description": "Encoding. eg: \"utf-8\"", + "description": "File encoding.", "type": "string", "default": "utf-8" }, "ignoreDir": { - "description": "Ignore directories.", + "description": "List of ignored directories.", "type": "array", "default": [], "items": { @@ -1035,7 +1070,7 @@ } }, "ignoreGlobs": { - "description": "Ignore globs. eg: [\"**/*.lua\"]", + "description": "List of globs for ignored files.", "type": "array", "default": [], "items": { @@ -1043,7 +1078,7 @@ } }, "library": { - "description": "Library paths. eg: \"/usr/local/share/lua/5.1\"", + "description": "List of library roots.\n\nExample: `\"/usr/local/share/lua/5.1\"`.", "type": "array", "default": [], "items": { @@ -1051,7 +1086,7 @@ } }, "moduleMap": { - "description": "Module map. key is regex, value is new module regex\neg: {\n \"^(.*)$\": \"module_$1\"\n \"^lib(.*)$\": \"script$1\"\n}", + "description": "Module map. Allows customizing conversion from file paths\nto module names and require paths.\n\nThis is a list of objects, each containing a regular expression\nand a replace string. When generating module name for a file,\nEmmyLua will reverse-match file path with require patterns,\ngenerate an appropriate module name, then run it through these replace\npatterns to get the final module name.\n\nExample:\n\n```json\n{\n \"workspace\": {\n \"moduleMap\": [\n {\n \"pattern\": \"^_core\\\\.public\\\\.(.*)$\",\n \"replace\": \"@core.$1\"\n }\n ]\n }\n}\n```", "type": "array", "default": [], "items": { @@ -1072,7 +1107,7 @@ "x-vscode-setting": true }, "workspaceRoots": { - "description": "Workspace roots. eg: [\"src\", \"test\"]", + "description": "List of workspace roots.\n\nExample: `[\"src\", \"test\"]`.", "type": "array", "default": [], "items": { @@ -1085,9 +1120,11 @@ "type": "object", "properties": { "pattern": { + "description": "Regular expression that will be matched against the generated module\nname. See [regex] crate for details about syntax.\n\n[regex]: https://docs.rs/regex/latest/regex/#syntax", "type": "string" }, "replace": { + "description": "Replace string. Use `$name` to substitute capturing groups from regex.", "type": "string" } }, diff --git a/crates/emmylua_code_analysis/resources/std/builtin.lua b/crates/emmylua_code_analysis/resources/std/builtin.lua index 3ac36d4e7..48133bd99 100644 --- a/crates/emmylua_code_analysis/resources/std/builtin.lua +++ b/crates/emmylua_code_analysis/resources/std/builtin.lua @@ -16,90 +16,142 @@ -- Built-in Types ---- ---- The type *nil* has one single value, **nil**, whose main property is to be +--- The type {lua}`nil` has one single value, *nil*, whose main property is to be --- different from any other value; it usually represents the absence of a --- useful value. ---@class nil ---- ---- The type *boolean* has two values, **false** and **true**. Both **nil** and ---- **false** make a condition false; any other value makes it true. +--- The type {lua}`boolean` has two values, *false* and *true*. +--- Both {lua}`nil` and *false* make a condition false; any other value +--- makes it true. ---@class boolean +--- Lua uses two internal representations for numbers: *integer* and *float*. +--- It has explicit rules about when each representation is used, +--- but it also converts between them automatically as needed. +--- +--- EmmyLua, on the other hand, allows explicitly annotating which representation +--- is expected. The {lua}`number` type can contain both *integer* and *float* +--- values. The {lua}`integer` is a sub-type of {lua}`number`, and only allows +--- *integer* values. --- ---- The type *number* uses two internal representations, or two subtypes, one ---- called *integer* and the other called *float*. Lua has explicit rules about ---- when each representation is used, but it also converts between them ---- automatically as needed. Therefore, the programmer may choose to mostly ---- ignore the difference between integers and floats or to assume complete ---- control over the representation of each number. Standard Lua uses 64-bit ---- integers and double-precision (64-bit) floats, but you can also compile ---- Lua so that it uses 32-bit integers and/or single-precision (32-bit) ---- floats. The option with 32 bits for both integers and floats is ---- particularly attractive for small machines and embedded systems. (See ---- macro LUA_32BITS in file luaconf.h.) +--- ```{seealso} +--- Lua's [manual on value types]. +--- ``` +--- +--- [manual on value types]: https://www.lua.org/manual/5.4/manual.html#2.1 ---@class number +--- The type {lua}`integer` is a sub-type of {lua}`number` that only allows numbers +--- with *integer* representation. ---@class integer ---- ---- The type *userdata* is provided to allow arbitrary C data to be stored in +--- The type {lua}`userdata` is provided to allow arbitrary C data to be stored in --- Lua variables. A userdata value represents a block of raw memory. There ---- are two kinds of userdata: *full userdata*, which is an object with a block ---- of memory managed by Lua, and *light userdata*, which is simply a C pointer ---- value. Userdata has no predefined operations in Lua, except assignment ---- and identity test. By using *metatables*, the programmer can define ---- operations for full userdata values. Userdata values cannot be ---- created or modified in Lua, only through the C API. This guarantees the ---- integrity of data owned by the host program. +--- are two kinds of userdata: {lua}`userdata`, which is an object with a block +--- of memory managed by Lua, and {lua}`lightuserdata`, which is simply a C pointer +--- value. +--- +--- ```{seealso} +--- Lua's [manual on value types]. +--- ``` +--- +--- [manual on value types]: https://www.lua.org/manual/5.4/manual.html#2.1 ---@class userdata +--- The type {lua}`lightuserdata` is a sub-type of {lua}`userdata` that only allows +--- values with *light userdata* representation. ---@class lightuserdata ---- ---- The type *thread* represents independent threads of execution and it is +--- The type {lua}`thread` represents independent threads of execution and it is --- used to implement coroutines. Lua threads are not related to --- operating-system threads. Lua supports coroutines on all systems, even those --- that do not support threads natively. ---@class thread ---- --- The type *table* implements associative arrays, that is, arrays that can ---- have as indices not only numbers, but any Lua value except **nil** and NaN. ---- (*Not a Number* is a special floating-point value used by the IEEE 754 ---- standard to represent undefined or unrepresentable numerical results, such ---- as `0/0`.) Tables can be heterogeneous; that is, they can contain values of ---- all types (except **nil**). Any key with value **nil** is not considered ---- part oft he table. Conversely, any key that is not part of a table has an ---- a ssociated value **nil**. ---- ---- Tables are the sole data-structuring mechanism in Lua; they can be used to ---- represent ordinary arrays, lists, symbol tables, sets, records, graphs, ---- trees, etc. To represent records, Lua uses the field name as an index. The ---- language supports this representation by providing `a.name` as syntactic ---- sugar for `a["name"]`. There are several convenient ways to create tables ---- in Lua. ---- ---- Like indices, the values of table fields can be of any type. In particular, ---- because functions are first-class values, table fields can contain functions. ---- Thus tables can also carry *methods*. ---- ---- The indexing of tables follows the definition of raw equality in the ---- language. The expressions `a[i]` and `a[j]` denote the same table element ---- if and only if `i` and `j` are raw equal (that is, equal without ---- metamethods). In particular, floats with integral values are equal to ---- their respective integers. To avoid ambiguities, any float with integral ---- value used as a key is converted to its respective integer. For instance, ---- if you write `a[2.0] = true`, the actual key inserted into the table will ---- be the integer `2`. (On the other hand, 2 and "`2`" are different Lua ---- values and therefore denote different table entries.) ----@class table +--- have as indices not only numbers, but any Lua value except {lua}`nil` and +--- {lua}`NaN `. (*Not a Number* is a special floating-point value used +--- by the IEEE 754 standard to represent undefined or unrepresentable numerical +--- results, such as `0/0`.) +--- +--- While lua allows mixing types of keys and values in a table, EmmyLua has +--- an option to specify their exact types. Simply using type `table` creates +--- a heterogeneous table (equivalent to `table`), while explicitly +--- providing key and value types creates a homogeneous table: +--- +--- ```lua +--- --- @type table +--- local tableWithArbitraryData = {} +--- +--- --- @type table +--- local tableWithStringKeysAndIntValues = {} +--- ``` +--- +--- You can also specify the exact shape of a table by using a *table literal*: +--- +--- ```lua +--- --- @type { username: string, age: integer } +--- local User = { ... } +--- ``` +--- +--- ```{seealso} +--- Lua's [manual on value types]. +--- ``` +--- +--- [manual on value types]: https://www.lua.org/manual/5.4/manual.html#2.1 +---@class table +--- The type {lua}`any` is compatible with any other type. That is, all types +--- can be converted to and from {lua}`any`. +--- +--- This type is a way to bypass type checking system and explicitly tell EmmyLua +--- that you know what you're doing. +--- +--- ```{tip} +--- Prefer using {lua}`unknown` instead of {lua}`any` to signal the need +--- to be careful and explicitly check value's contents. +--- ``` ---@class any +--- The type {lua}`unknown` is similar to {lua}`any`, +--- but signifies a different intent. +--- +--- While {lua}`any` is a way to say "I know what I'm doing", {lua}`unknown` +--- is a way to say "better check this value before using it". +---@class unknown + +--- Void is an alias for {lua}`nil` used in some code bases. Prefer using +--- {lua}`nil` instead. ---@class void +--- A special type used with class methods. It can be thought of +--- as a generic parameter that matches type of the function's implicit argument +--- `self`. That is, when a function is called via colon notation +--- (i.e. `table:method()`), {lua}`self` is replaced with the type +--- of expression before the colon. +--- +--- This is especially handy when dealing with inheritance. +--- Consider the following example: +--- +--- ```lua +--- --- @class Base +--- local Base = {} +--- +--- --- @return self +--- function Base:new() +--- return setmetatable({}, { __index=self }) +--- end +--- +--- --- @class Child: Base +--- local Child = setmetatable({}, { __index=Base }) +--- +--- local child = Child:new() +--- ``` +--- +--- Here, EmmyLua infers type of `child` to be `Child`, even though `new` +--- was defined in its base class. This is because `new` uses {lua}`self` +--- as its return type. ---@class self ---@alias int integer @@ -108,26 +160,100 @@ ---@class function +--- A type for {lua}`assert` function. Given a nullable type `T` +--- expands to a non-nullable version of `T`. +--- +--- For example, if `T` is `string?`, then `std.NotNull` will +--- be `string`. ---@alias std.NotNull T - ? +--- An opposite of {lua}`std.NotNull`. Given a type `T`, expands +--- to a nullable version of `T`. +--- +--- ```{tip} +--- Prefer using `T?` or `T | nil` instead. +--- ``` ---@alias std.Nullable T + ? --- built-in type for Select function ---@alias std.Select unknown +--- A type for {lua}`table.unpack` function. Given a type `T` +--- and optional literal types `Start` and `End`, expands +--- to the type of expression `table.unpack(t, start, end)`. --- ---- built-in type for Unpack function +--- Example: +--- +--- ```lua +--- --- @generic T +--- --- @param list T +--- --- @return std.Unpack +--- function customUnpack(list) end +--- +--- local a, b, c = customUnpack({1, 2, 3}) +--- ``` +--- +--- Here, `a`, `b` and `c` will be inferred as integers. ---@alias std.Unpack unknown +--- A type for {lua}`rawget` function. Given a type `T` +--- and a literal type `K`, expands to the type of expression +--- `rawget(t, k)`. +--- +--- Example: +--- +--- ```lua +--- --- @class Example +--- --- @field value integer --- ---- built-in type for Rawget +--- --- @type std.RawGet +--- local value +--- ``` +--- +--- Here, `std.RawGet` will be expanded to `integer`. ---@alias std.RawGet unknown +--- A wrapper for matching literal types in generics. +--- +--- By default, generics variables that match literal values +--- decay to values' base types: +--- +--- ```lua +--- --- @generic T +--- --- @param x T +--- --- @return T +--- local function id(x) +--- return x +--- end +--- +--- local original --- @type "literal" +--- +--- local value = id(original) +--- ``` +--- +--- Here, type of `value` will be inferred as `string` +--- even though `original`'s type was `"literal"`. +--- +--- We can prevent this behavior by wrapping generic pattern for `T` +--- into `std.ConstTpl`: +--- +--- ```lua +--- --- @generic T +--- --- @param x std.ConstTpl +--- --- @return T +--- local function id(x) +--- return x +--- end +--- +--- local original --- @type "literal" +--- +--- local value = id(original) +--- ``` --- ---- built-in type for generic template, for match integer const and true/false +--- Here, type of `value` will be inferred as `"literal"`. ---@alias std.ConstTpl unknown ---- compact luals +--- compat luals ---@alias type std.type diff --git a/crates/emmylua_code_analysis/src/config/configs/code_action.rs b/crates/emmylua_code_analysis/src/config/configs/code_action.rs index 317414e58..53b3c8e6d 100644 --- a/crates/emmylua_code_analysis/src/config/configs/code_action.rs +++ b/crates/emmylua_code_analysis/src/config/configs/code_action.rs @@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize}; pub struct EmmyrcCodeAction { /// Add space after `---` comments when inserting `@diagnostic disable-next-line`. #[serde(default = "default_false")] - #[schemars(extend("x-vscode-setting" = true))] pub insert_space: bool, } diff --git a/crates/emmylua_code_analysis/src/config/configs/completion.rs b/crates/emmylua_code_analysis/src/config/configs/completion.rs index 4484c1b46..d120cde25 100644 --- a/crates/emmylua_code_analysis/src/config/configs/completion.rs +++ b/crates/emmylua_code_analysis/src/config/configs/completion.rs @@ -5,30 +5,45 @@ use serde_with::{DefaultOnError, serde_as}; #[serde_as] #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] #[serde(rename_all = "camelCase")] -/// Configuration for EmmyLua code completion. pub struct EmmyrcCompletion { /// Enable autocompletion. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub enable: bool, - /// Automatically insert call to `require` when autocompletion - /// inserts objects from other modules. + + /// When enabled, selecting a completion suggestion from another + /// module will add the appropriate require statement. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub auto_require: bool, - /// The function used for auto-requiring modules. + + /// Name of the function that's inserted when auto-requiring modules. + /// + /// Default is `"require"`, but can be customized to use any module loader function. #[serde(default = "default_require_function")] pub auto_require_function: String, + /// The naming convention for auto-required filenames. + /// + /// Controls how the imported module names are formatted in the `require` statement. #[serde(default)] pub auto_require_naming_convention: EmmyrcFilenameConvention, - /// A separator used in auto-require paths. + + /// Defines the character used to separate path segments in require statements. + /// + /// Default is `"."`, but can be changed to other separators like `"/"`. #[serde(default = "default_auto_require_separator")] pub auto_require_separator: String, + /// Whether to use call snippets in completions. + /// + /// When enabled, function completions will insert a snippet with placeholders + /// for function arguments, allowing for quick tabbing between parameters. #[serde(default)] #[serde_as(deserialize_as = "DefaultOnError")] + #[schemars(extend("x-vscode-setting" = true))] pub call_snippet: bool, + /// Symbol that's used to trigger postfix autocompletion. #[serde(default = "default_postfix")] #[schemars(extend("x-vscode-setting" = { @@ -39,7 +54,10 @@ pub struct EmmyrcCompletion { "markdownEnumDescriptions": ["%config.common.enum.default.description%"], }))] pub postfix: String, - /// Whether to include the name in the base function completion. Effect: `function () end` -> `function name() end`. + + /// Whether to include the name in the base function in postfix autocompletion. + /// + /// Effect: `function () end` -> `function name() end`. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub base_function_includes_name: bool, @@ -76,18 +94,35 @@ fn default_auto_require_separator() -> String { ".".to_string() } +/// The naming convention for auto-required filenames. +/// +/// Controls how the imported module names are formatted in the `require` statement. #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, Copy)] #[serde(rename_all = "kebab-case")] pub enum EmmyrcFilenameConvention { - /// Keep the original filename. + /// Keep the original filename without any transformation. + /// + /// Example: `"my-module"` remains `"my-module"`. Keep, - /// Convert the filename to snake_case. + + /// Convert the filename to `snake_case`. + /// + /// Example: `"MyModule"` becomes `"my_module"`. SnakeCase, - /// Convert the filename to PascalCase. + + /// Convert the filename to `PascalCase`. + /// + /// Example: `"my_module"` becomes `"MyModule"`. PascalCase, - /// Convert the filename to camelCase. + + /// Convert the filename to `camelCase`. + /// + /// Example: `"my_module"` becomes `"myModule"`. CamelCase, - /// When returning class definition, use class name, otherwise keep original name. + + /// When returning a class definition, use the class name; otherwise keep the original name. + /// + /// This is useful for modules that export a single class with a name that might differ from the filename. KeepClass, } diff --git a/crates/emmylua_code_analysis/src/config/configs/diagnostics.rs b/crates/emmylua_code_analysis/src/config/configs/diagnostics.rs index 7d173348d..fd452e149 100644 --- a/crates/emmylua_code_analysis/src/config/configs/diagnostics.rs +++ b/crates/emmylua_code_analysis/src/config/configs/diagnostics.rs @@ -10,24 +10,34 @@ use crate::DiagnosticCode; #[serde(rename_all = "camelCase")] /// Represents the diagnostic configuration for Emmyrc. pub struct EmmyrcDiagnostic { - /// A list of diagnostic codes that are disabled. + /// A list of suppressed diagnostics. #[serde(default)] pub disable: Vec, - /// A flag indicating whether diagnostics are enabled. + + /// A flag indicating whether diagnostics are enabled at all. #[serde(default = "default_true")] pub enable: bool, + /// A list of global variables. + /// + /// Variables from this list are always treated as defined globals. #[serde(default)] pub globals: Vec, + /// A list of regular expressions for global variables. + /// + /// Variables that match these regular expressions are always treated as defined globals. #[serde(default)] pub globals_regex: Vec, + /// A map of diagnostic codes to their severity settings. #[serde(default)] pub severity: HashMap, - /// A list of diagnostic codes that are enabled. + + /// A list of diagnostic codes that are enabled, in addition to default ones. #[serde(default)] pub enables: Vec, + /// Delay between opening/changing a file and scanning it for errors, in milliseconds. #[schemars(extend("x-vscode-setting" = true))] pub diagnostic_interval: Option, diff --git a/crates/emmylua_code_analysis/src/config/configs/doc.rs b/crates/emmylua_code_analysis/src/config/configs/doc.rs index a8dfe9fe7..2c4d6361e 100644 --- a/crates/emmylua_code_analysis/src/config/configs/doc.rs +++ b/crates/emmylua_code_analysis/src/config/configs/doc.rs @@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] #[serde(rename_all = "camelCase")] pub struct EmmyrcDoc { - /// 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. + /// List of glob patterns that enable treating specific field names as private. + /// + /// For example, `m_*` would make fields `Type.m_id` and `Type.m_type` private. #[serde(default)] pub private_name: Vec, @@ -16,13 +18,17 @@ pub struct EmmyrcDoc { #[serde(default)] pub syntax: DocSyntax, - /// When `syntax` is `Myst` or `Rst`, specifies primary domain used + /// When `syntax` is `Myst` or `Rst`, specifies [primary domain] used /// with RST processor. + /// + /// [primary domain]: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-primary_domain #[serde(skip_serializing_if = "Option::is_none")] pub rst_primary_domain: Option, - /// When `syntax` is `Myst` or `Rst`, specifies default role used + /// When `syntax` is `Myst` or `Rst`, specifies [default role] used /// with RST processor. + /// + /// [default role]: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-default_role #[serde(skip_serializing_if = "Option::is_none")] pub rst_default_role: Option, } @@ -39,12 +45,32 @@ impl Default for EmmyrcDoc { } } +/// Syntax for highlighting documentation. #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] #[serde(rename_all = "kebab-case")] pub enum DocSyntax { + /// Documentation is not highlighted. None, + + /// Documentation is highlighted as plain [MarkDown]. + /// + /// [MarkDown]: https://commonmark.org/ Md, + + /// Documentation is highlighted as [MySt], a MarkDown plugin for [Sphinx]. + /// + /// Enables Autocompletion and Go To Definition for sphinx cross-references. + /// + /// [MySt]: https://myst-parser.readthedocs.io/ + /// [Sphinx]: https://www.sphinx-doc.org/ Myst, + + /// Documentation is highlighted as [ReStructured Text]. + /// + /// Enables Autocompletion and Go To Definition for [sphinx] cross-references. + /// + /// [ReStructured Text]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html + /// [sphinx]: https://www.sphinx-doc.org/ Rst, } diff --git a/crates/emmylua_code_analysis/src/config/configs/inlayhint.rs b/crates/emmylua_code_analysis/src/config/configs/inlayhint.rs index 49c8d63cc..a3ddb6f0b 100644 --- a/crates/emmylua_code_analysis/src/config/configs/inlayhint.rs +++ b/crates/emmylua_code_analysis/src/config/configs/inlayhint.rs @@ -8,10 +8,12 @@ pub struct EmmyrcInlayHint { #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub enable: bool, + /// Show parameter names in function calls and parameter types in function definitions. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub param_hint: bool, + /// Show named array indexes. /// /// Example: @@ -26,19 +28,23 @@ pub struct EmmyrcInlayHint { #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub index_hint: bool, + /// Show types of local variables. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub local_hint: bool, + /// Show methods that override functions from base class. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub override_hint: bool, + /// Show hint when calling an object results in a call to /// its meta table's `__call` function. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub meta_call_hint: bool, + /// Show name of enumerator when passing a literal value to a function /// that expects an enum. /// diff --git a/crates/emmylua_code_analysis/src/config/configs/references.rs b/crates/emmylua_code_analysis/src/config/configs/references.rs index df5cf1c8c..7c1260a0b 100644 --- a/crates/emmylua_code_analysis/src/config/configs/references.rs +++ b/crates/emmylua_code_analysis/src/config/configs/references.rs @@ -8,11 +8,13 @@ pub struct EmmyrcReference { #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub enable: bool, + /// Use fuzzy search when searching for symbol usages /// and normal search didn't find anything. #[serde(default = "default_true")] #[schemars(extend("x-vscode-setting" = true))] pub fuzzy_search: bool, + /// Also search for usages in strings. #[serde(default = "default_false")] #[schemars(extend("x-vscode-setting" = true))] diff --git a/crates/emmylua_code_analysis/src/config/configs/reformat.rs b/crates/emmylua_code_analysis/src/config/configs/reformat.rs index 8d2bc490d..580b2132d 100644 --- a/crates/emmylua_code_analysis/src/config/configs/reformat.rs +++ b/crates/emmylua_code_analysis/src/config/configs/reformat.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct EmmyrcReformat { - /// Whether to enable internal code reformatting. + /// Configuration for external formatting tool. #[serde(default)] pub external_tool: Option, @@ -19,9 +19,33 @@ pub struct EmmyrcExternalTool { /// The command to run the external tool. #[serde(default)] pub program: String, - /// The arguments to pass to the external tool. + + /// List of arguments to pass to the external tool. + /// + /// Each argument can contain the following patterns: + /// + /// - `${file}` expands to the file path that needs formatting; + /// + /// - `${indent_size}` expands to numeric value for indentation size; + /// + /// - `${use_tabs?:}` expands to `` placeholder or + /// `` placeholder depending on whether tabs are used + /// for indentation. + /// + /// For example, `${use_tabs?--tabs}` will expand to `--tabs` if tabs + /// are required, or an empty string if tabs are not required. + /// + /// - `${insert_final_newline?:}` expands to `` + /// placeholder or `` placeholder depending on whether the tool + /// should insert final newline. + /// + /// - `${non_standard_symbol?:}` expands to `` + /// placeholder or `` placeholder depending on whether + /// non-standard symbols are enabled. #[serde(default)] pub args: Vec, + + /// Command timeout, in milliseconds. #[serde(default = "default_timeout")] pub timeout: u64, } diff --git a/crates/emmylua_code_analysis/src/config/configs/resource.rs b/crates/emmylua_code_analysis/src/config/configs/resource.rs index 85f767ab8..b49322140 100644 --- a/crates/emmylua_code_analysis/src/config/configs/resource.rs +++ b/crates/emmylua_code_analysis/src/config/configs/resource.rs @@ -4,6 +4,13 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, JsonSchema, Default, Clone)] #[serde(rename_all = "camelCase")] pub struct EmmyrcResource { + /// List of resource directories used in a project. Files from these + /// directories will be added to autocompletion when completing + /// file paths. + /// + /// This list can contain anything, like directories with game assets, + /// template files, and so on. No special interpretation beyond + /// autocompletion is given to these paths. #[serde(default)] pub paths: Vec, } diff --git a/crates/emmylua_code_analysis/src/config/configs/runtime.rs b/crates/emmylua_code_analysis/src/config/configs/runtime.rs index a521e34e7..bac6e37d6 100644 --- a/crates/emmylua_code_analysis/src/config/configs/runtime.rs +++ b/crates/emmylua_code_analysis/src/config/configs/runtime.rs @@ -8,22 +8,33 @@ pub struct EmmyrcRuntime { /// Lua version. #[serde(default)] pub version: EmmyrcLuaVersion, + #[serde(default)] - /// Functions that like require. + /// Functions that are treated like `require`. pub require_like_function: Vec, + #[serde(default)] - /// Framework versions. pub framework_versions: Vec, + + /// Extensions of Lua files that need analysis. + /// + /// Example: `[".lua", ".lua.txt"]`. #[serde(default)] - /// file Extensions. eg: .lua, .lua.txt pub extensions: Vec, + + /// Require pattern in the format of Lua's [`path`]. + /// + /// Example: `["?.lua", "?/init.lua"]`. + /// + /// [`path`]: https://www.lua.org/pil/8.1.html #[serde(default)] - /// Require pattern. eg. "?.lua", "?/init.lua" pub require_pattern: Vec, + + /// Controls resolution of class constructors. #[serde(default)] - /// class default overload function. pub class_default_call: ClassDefaultCall, - /// Non-standard symbols. + + /// List of enabled non-standard symbols. #[serde(default)] pub nonstandard_symbol: Vec, } @@ -62,7 +73,7 @@ pub enum EmmyrcLuaVersion { /// Lua 5.5 #[serde(rename = "Lua5.5", alias = "Lua 5.5")] Lua55, - /// Lua Latest + /// Lua Latest, currently set to `Lua5.4`. #[serde(rename = "LuaLatest", alias = "Lua Latest")] LuaLatest, } @@ -90,13 +101,31 @@ impl EmmyrcLuaVersion { #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct ClassDefaultCall { + /// Name of the method that's used to resolve class default `__call` operator. + /// + /// For example, if `functionName` is `"__init"`, then EmmyLua will use parameters + /// and return types of `__init` method as parameters and return types + /// of class' `__call` operator: + /// + /// ```lua + /// --- @class Example + /// --- @field __init fun(): Example + /// + /// -- Unless `Example` provides its own `@overload`, + /// -- any call to `Example()` is treated as a call to `Example:__init()`: + /// local example = Example() + /// -- ^^^^^^^ type of `example` is inferred as `Example`. + /// ``` #[serde(default)] - /// class default overload function. eg. "__init". pub function_name: String, + + /// Remove the `self` parameter from list of constructor parameters + /// when inferring constructor signature using `functionName`. #[serde(default = "default_true")] - /// Mandatory non`:` definition. When `function_name` is not empty, it takes effect. pub force_non_colon: bool, - /// Force to return `self`. + + /// Always use `self` as constructor's return type when inferring + /// constructor signature using `functionName`. #[serde(default = "default_true")] pub force_return_self: bool, } diff --git a/crates/emmylua_code_analysis/src/config/configs/signature.rs b/crates/emmylua_code_analysis/src/config/configs/signature.rs index 5c0660cd2..12e7f08d4 100644 --- a/crates/emmylua_code_analysis/src/config/configs/signature.rs +++ b/crates/emmylua_code_analysis/src/config/configs/signature.rs @@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize}; pub struct EmmyrcSignature { /// Whether to enable signature help. #[serde(default = "default_true")] + #[schemars(extend("x-vscode-setting" = true))] pub detail_signature_helper: bool, } diff --git a/crates/emmylua_code_analysis/src/config/configs/strict.rs b/crates/emmylua_code_analysis/src/config/configs/strict.rs index 89401371b..043899dee 100644 --- a/crates/emmylua_code_analysis/src/config/configs/strict.rs +++ b/crates/emmylua_code_analysis/src/config/configs/strict.rs @@ -13,18 +13,25 @@ fn default_false() -> bool { #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] #[serde(rename_all = "camelCase")] pub struct EmmyrcStrict { - /// Whether to enable strict mode require path. + /// Whether to enable strict mode for resolving require paths. #[serde(default)] pub require_path: bool, + #[serde(default)] pub type_call: bool, - /// Whether to enable strict mode array indexing. + + /// Whether to enable strict mode when inferring type + /// of array indexing operation. #[serde(default = "default_true")] pub array_index: bool, - /// meta define overrides file define + + /// Definitions from `@meta` files always overrides definitions + /// from normal files. #[serde(default = "default_true")] pub meta_override_file_define: bool, - /// Base constant types defined in doc can match base types, allowing int to match `---@alias id 1|2|3`, same for string. + + /// Base constant types defined in doc can match base types, allowing `int` + /// to match `---@alias id 1|2|3`, same for string. #[serde(default = "default_false")] pub doc_base_const_match_base_type: bool, } diff --git a/crates/emmylua_code_analysis/src/config/configs/workspace.rs b/crates/emmylua_code_analysis/src/config/configs/workspace.rs index 3ef90c6b1..508d656c2 100644 --- a/crates/emmylua_code_analysis/src/config/configs/workspace.rs +++ b/crates/emmylua_code_analysis/src/config/configs/workspace.rs @@ -4,35 +4,65 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] #[serde(rename_all = "camelCase")] pub struct EmmyrcWorkspace { - /// Ignore directories. + /// List of ignored directories. #[serde(default)] pub ignore_dir: Vec, - /// Ignore globs. eg: ["**/*.lua"] + + /// List of globs for ignored files. #[serde(default)] pub ignore_globs: Vec, + + /// List of library roots. + /// + /// Example: `"/usr/local/share/lua/5.1"`. #[serde(default)] - /// Library paths. eg: "/usr/local/share/lua/5.1" pub library: Vec, + + /// List of workspace roots. + /// + /// Example: `["src", "test"]`. #[serde(default)] - /// Workspace roots. eg: ["src", "test"] pub workspace_roots: Vec, + // unused #[serde(default)] pub preload_file_size: i32, - /// Encoding. eg: "utf-8" + + /// File encoding. #[serde(default = "encoding_default")] pub encoding: String, - /// Module map. key is regex, value is new module regex - /// eg: { - /// "^(.*)$": "module_$1" - /// "^lib(.*)$": "script$1" + + /// Module map. Allows customizing conversion from file paths + /// to module names and require paths. + /// + /// This is a list of objects, each containing a regular expression + /// and a replace string. When generating module name for a file, + /// EmmyLua will reverse-match file path with require patterns, + /// generate an appropriate module name, then run it through these replace + /// patterns to get the final module name. + /// + /// Example: + /// + /// ```json + /// { + /// "workspace": { + /// "moduleMap": [ + /// { + /// "pattern": "^_core\\.public\\.(.*)$", + /// "replace": "@core.$1" + /// } + /// ] + /// } /// } + /// ``` #[serde(default)] pub module_map: Vec, + /// Delay between changing a file and full project reindex, in milliseconds. #[serde(default = "reindex_duration_default")] #[schemars(extend("x-vscode-setting" = true))] pub reindex_duration: u64, + /// Enable full project reindex after changing a file. #[serde(default = "enable_reindex_default")] #[schemars(extend("x-vscode-setting" = true))] @@ -57,7 +87,13 @@ impl Default for EmmyrcWorkspace { #[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)] pub struct EmmyrcWorkspaceModuleMap { + /// Regular expression that will be matched against the generated module + /// name. See [regex] crate for details about syntax. + /// + /// [regex]: https://docs.rs/regex/latest/regex/#syntax pub pattern: String, + + /// Replace string. Use `$name` to substitute capturing groups from regex. pub replace: String, } diff --git a/crates/emmylua_code_analysis/src/config/mod.rs b/crates/emmylua_code_analysis/src/config/mod.rs index a35fa30c8..d074fca59 100644 --- a/crates/emmylua_code_analysis/src/config/mod.rs +++ b/crates/emmylua_code_analysis/src/config/mod.rs @@ -28,38 +28,72 @@ pub struct Emmyrc { #[serde(rename = "$schema")] #[serde(skip_serializing_if = "Option::is_none")] pub schema: Option, + + /// Configuration for code completion features. #[serde(default)] pub completion: EmmyrcCompletion, + + /// Configuration for diagnostics and error detection. #[serde(default)] pub diagnostics: EmmyrcDiagnostic, + + /// Configuration for function signature help. #[serde(default)] pub signature: EmmyrcSignature, + + /// Configuration for inlay hints in the editor. #[serde(default)] pub hint: EmmyrcInlayHint, + + /// Configuration for Lua runtime. #[serde(default)] pub runtime: EmmyrcRuntime, + + /// Configuration for workspace management. #[serde(default)] pub workspace: EmmyrcWorkspace, + + /// Configuration for resource file management. #[serde(default)] pub resource: EmmyrcResource, + + /// Configuration for code lens features. #[serde(default)] pub code_lens: EmmyrcCodeLens, + + /// Configuration for strict type checks. #[serde(default)] pub strict: EmmyrcStrict, + + /// Configuration for semantic token highlighting. #[serde(default)] pub semantic_tokens: EmmyrcSemanticToken, + + /// Configuration for reference lookup features. #[serde(default)] pub references: EmmyrcReference, + + /// Configuration for hover information. #[serde(default)] pub hover: EmmyrcHover, + + /// Configuration for document color features. #[serde(default)] pub document_color: EmmyrcDocumentColor, + + /// Configuration for code actions and quick fixes. #[serde(default)] pub code_action: EmmyrcCodeAction, + + /// Configuration for inline value display. #[serde(default)] pub inline_values: EmmyrcInlineValues, + + /// Configuration for documentation parsing. #[serde(default)] pub doc: EmmyrcDoc, + + /// Configuration for code formatting. #[serde(default)] pub format: EmmyrcReformat, } diff --git a/docs/v2/.gitignore b/docs/v2/.gitignore new file mode 100644 index 000000000..03ba263a3 --- /dev/null +++ b/docs/v2/.gitignore @@ -0,0 +1,203 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock +#poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +#pdm.lock +#pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +#pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +.vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml diff --git a/docs/v2/.vscode/launch.json b/docs/v2/.vscode/launch.json new file mode 100644 index 000000000..a1b5e9142 --- /dev/null +++ b/docs/v2/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": false, + } + ] +} diff --git a/docs/v2/.vscode/settings.json b/docs/v2/.vscode/settings.json new file mode 100644 index 000000000..a281e49a9 --- /dev/null +++ b/docs/v2/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python-envs.defaultEnvManager": "ms-python.python:system", + "python-envs.pythonProjects": [] +} diff --git a/docs/v2/Makefile b/docs/v2/Makefile new file mode 100644 index 000000000..57fa8a491 --- /dev/null +++ b/docs/v2/Makefile @@ -0,0 +1,35 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -j auto -n +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +LANGUAGE ?= en +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help html html-root html-all update-translation Makefile + +html-root: + mkdir -p build/html/ + cp -r "$(SOURCEDIR)/_root/." "$(BUILDDIR)/html/" + +html: html-root + @$(SPHINXBUILD) -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)/html/$(LANGUAGE)" -D language="$(LANGUAGE)" $(SPHINXOPTS) $(O) + +html-all: html-root + @$(SPHINXBUILD) -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)/html/en" -D language="en" $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)/html/zh" -D language="zh" $(SPHINXOPTS) $(O) + +update-translation: + rm -rf "$(BUILDDIR)/gettext" + @$(SPHINXBUILD) -M gettext "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + sphinx-intl update -p "$(BUILDDIR)/gettext" -l zh + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -D language="$(LANGUAGE)" $(SPHINXOPTS) $(O) diff --git a/docs/v2/requirements.txt b/docs/v2/requirements.txt new file mode 100644 index 000000000..bcdc6786c --- /dev/null +++ b/docs/v2/requirements.txt @@ -0,0 +1,8 @@ +Sphinx~=8.2 +sphinx-intl~=2.3 +get-version~=3.5 +myst-parser~=4.0 +sphinx_immaterial~=0.13 +sphinx-lua-ls~=3.0 +frozendict~=2.4 +referencing~=0.36.2 diff --git a/docs/v2/source/_extensions/emmyrc/__init__.py b/docs/v2/source/_extensions/emmyrc/__init__.py new file mode 100644 index 000000000..0488c4a2b --- /dev/null +++ b/docs/v2/source/_extensions/emmyrc/__init__.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from emmyrc.auto import AutodocDirective, ExampleValue +from emmyrc.domain import EmmyRcDomain +from sphinx.application import Sphinx + + +def suppress_auto_ref_warnings(app, domain, node): + if node["refdomain"] == "emmyrc" and node["reftype"] == "_auto": + return True + + +def setup(app: Sphinx): + app.add_domain(EmmyRcDomain) + app.add_directive_to_domain("emmyrc", "auto", AutodocDirective) + app.add_directive_to_domain("emmyrc", "auto-example", ExampleValue) + app.add_config_value("emmylua_schema", None, "html", str) + app.connect("warn-missing-reference", suppress_auto_ref_warnings) + return { + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/v2/source/_extensions/emmyrc/auto.py b/docs/v2/source/_extensions/emmyrc/auto.py new file mode 100644 index 000000000..8818f00fb --- /dev/null +++ b/docs/v2/source/_extensions/emmyrc/auto.py @@ -0,0 +1,402 @@ +import contextlib +import dataclasses +import json +import typing as _t +from typing import Set, Tuple + +import docutils.nodes +import docutils.statemachine +import sphinx.addnodes +import sphinx.directives +import sphinx.directives.code +import sphinx_immaterial.code_annotations +from docutils.parsers.rst import directives +from emmyrc.domain import EmmyRcObject +from emmyrc.loader import ( + UNKNOWN, + AllOf, + Any, + Array, + Boolean, + Enum, + Integer, + Loader, + Null, + Number, + Object, + OneOf, + Ref, + String, + Type, + load_jsons, +) +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective + +logger = logging.getLogger("emmyrc") + + +def parse_list_option(value: str | None): + if not value: + return [] + else: + return value.split(",") + + +class AutoEmmyRcObject(EmmyRcObject): + def __init__( + self, + *args, + uri: str, + path: str, + root: Type, + loader: Loader, + rendered: set[str], + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.uri = uri + self.path = path + self.root = root + self.loader = loader + self.rendered = rendered + + def run(self) -> list[docutils.nodes.Node]: + if (self.uri, self.path) in self.options.get("exclude", []): + return [] + self.rendered.add(self.root.id) + return super().run() + + def transform_content(self, content_node: sphinx.addnodes.desc_content) -> None: + if self.root.description: + content_node += self.parse_text_to_nodes(self.root.description) + if "recursive" in self.options: + content_node += self.render_children(self.root) + + def render_children(self, root: Type) -> list[docutils.nodes.Node]: + root = root.unwrap_optional() + if isinstance(root, Object) and root.named_children: + return self.render_object_children(root) + elif isinstance(root, Enum) and root.items: + return self.render_enum_children(root) + else: + nodes = [] + for ref in root.find_refs(): + if self.loader.can_inline(ref.ref): + nodes.extend(self.render_children(self.loader.load(ref.ref))) + return nodes + + def render_object_children(self, root: Object) -> list[docutils.nodes.Node]: + nodes = [] + default = root.default + if not isinstance(default, dict): + default = {} + for name, type in root.named_children.items(): + unwrapped = type.unwrap_optional() + if isinstance(unwrapped, Ref) and self.loader.can_inline(unwrapped.ref): + ref = self.loader.load(unwrapped.ref) or Any() + type = dataclasses.replace( + ref, + title=type.title or ref.title, + description=type.description or ref.description, + deprecated=type.deprecated or ref.deprecated, + required=type.required or ref.required, + ) + type = dataclasses.replace(type, default=default.get(name, type.default)) + nodes.extend(self.render_child(name, type)) + return nodes + + def render_enum_children(self, root: Enum) -> list[docutils.nodes.Node]: + nodes = [] + + for type in root.items: + name = type.print(self.loader) + nodes.extend( + AutoEmmyRcObject( + "emmyrc:property", + [name], + self.options, + self.content, + self.lineno, + self.content_offset, + self.block_text, + self.state, + self.state_machine, + uri=self.uri, + path=".".join(filter(None, [self.path, name])), + root=type, + loader=self.loader, + rendered=self.rendered, + ).run() + ) + + return nodes + + def render_child(self, name: str, root: Type) -> list[docutils.nodes.Node]: + arg = name + unwrapped_root = root.unwrap_optional() + if not (isinstance(unwrapped_root, Object) and unwrapped_root.named_children): + if self.loader.can_inline(root.id) and not isinstance(unwrapped_root, Enum): + arg += f": {root.print(self.loader)}" + if root.default is not UNKNOWN: + arg += f" = {json.dumps(root.default)}" + elif root.is_optional(): + arg += f" = null" + + return AutoEmmyRcObject( + "emmyrc:object", + [arg], + self.options, + self.content, + self.lineno, + self.content_offset, + self.block_text, + self.state, + self.state_machine, + uri=self.uri, + path=".".join(filter(None, [self.path, name])), + root=root, + loader=self.loader, + rendered=self.rendered, + ).run() + + def get_display_prefix(self) -> list[docutils.nodes.Node]: + prefix = [] + if self.root.required: + prefix.append(sphinx.addnodes.desc_sig_keyword("required", "required")) + prefix.append(sphinx.addnodes.desc_sig_space()) + return prefix + + +class AutodocDirective(SphinxDirective): + required_arguments = 1 + optional_arguments = 0 + option_spec = { + "recursive": directives.flag, + "unwrap": directives.flag, + "title": directives.unchanged, + "exclude": parse_list_option, + **EmmyRcObject.option_spec, + } + has_content = True + + def run(self) -> list[docutils.nodes.Node]: + loader = Loader(load_jsons(self.env.app)) + root = loader.load(self.arguments[0]) + + excludes = set() + exclude: str + for exclude in self.options.get("exclude", []): + parts = exclude.strip().split(maxsplit=1) + match len(parts): + case 1: + excludes.add((loader.load(parts[0]).id, "")) + case 2: + excludes.add((loader.load(parts[0]).id, parts[1])) + case _: + pass + self.options["exclude"] = excludes + + rendered = set() + + nodes = self.render_root(True, loader, root, rendered) + + if "recursive" not in self.options: + return nodes + + title = "Config types" + section = docutils.nodes.section("", names=[]) + section["name"] = docutils.nodes.fully_normalize_name(title) + section["names"].append(section["name"]) + section += docutils.nodes.title("", title) + for uri, type in loader.get_all_loaded(): + if uri not in rendered and not loader.can_inline(uri): + section += self.render_root(False, loader, type, rendered) + + if len(section) > 1: + nodes.append(section) + self.state.document.note_implicit_target(section, section) + + return nodes + + def render_root( + self, top_level: bool, loader: Loader, root: Type, rendered: set[str] + ) -> list[docutils.nodes.Node]: + if ( + "unwrap" in self.options + and isinstance(root, Object) + and root.named_children + ): + return self.render_unwrapped(top_level, loader, root, rendered) + else: + return self.render_wrapped( + root.id, top_level, loader, root, root.id, rendered, "" + ) + + def render_unwrapped( + self, top_level: bool, loader: Loader, root: Object, rendered: set[str] + ) -> list[docutils.nodes.Node]: + if (root.id, "") in self.options.get("exclude", []): + return [] + + rendered.add(root.id) + + nodes = [] + + if top_level: + nodes.extend(self.parse_content_to_nodes()) + if root.description: + nodes.extend(self.parse_text_to_nodes(root.description)) + + default = root.default + if not isinstance(default, dict): + default = {} + for name, type in root.named_children.items(): + unwrapped = type.unwrap_optional() + if isinstance(unwrapped, Ref) and loader.can_inline(unwrapped.ref): + ref = loader.load(unwrapped.ref) or Any() + type = dataclasses.replace( + ref, + title=type.title or ref.title, + description=type.description or ref.description, + deprecated=type.deprecated or ref.deprecated, + required=type.required or ref.required, + default=default.get(name, type.default), + ) + arg = f"{root.id}.{name}" + unwrapped = type.unwrap_optional() + if not (isinstance(unwrapped, Object) and unwrapped.named_children): + if loader.can_inline(root.id) and not isinstance(unwrapped, Enum): + arg += f": {root.print(loader)}" + if root.default is not UNKNOWN: + arg += f" = {json.dumps(root.default)}" + nodes.extend(self.render_wrapped( + arg, False, loader, type, root.id, rendered, name + )) + + return nodes + + def render_wrapped( + self, + arg: str, + top_level: bool, + loader: Loader, + root: Type, + uri: str, + rendered: set[str], + path: str, + ) -> list[docutils.nodes.Node]: + return AutoEmmyRcObject( + "emmyrc:object", + [arg], + self.options, + self.content if top_level else docutils.statemachine.StringList(), + self.lineno if top_level else 0, + self.content_offset if top_level else 0, + self.block_text if top_level else "", + self.state, + self.state_machine, + uri=uri, + path=path, + root=root, + loader=loader, + rendered=rendered, + ).run() + + +class ExampleValue(SphinxDirective): + required_arguments = 1 + optional_arguments = 0 + option_spec = { + "kind": lambda value: directives.choice(value, ["all", "user", "project"]) + } + + def run(self) -> list[docutils.nodes.Node]: + self.loader = Loader(load_jsons(self.env.app)) + root = self.loader.load(self.arguments[0]) + + self.lines: list[str] = [] + self.chunks: list[str] = [] + self.indent = 0 + + self.render_type(root, root.default) + self.newline() + + return sphinx.directives.code.CodeBlock( + "code-block", + ["json"], + {}, + docutils.statemachine.StringList(self.lines), + self.lineno, + self.content_offset, + self.block_text, + self.state, + self.state_machine, + ).run() + + @contextlib.contextmanager + def indented(self): + self.indent += 1 + yield + self.indent -= 1 + + def newline(self): + self.lines.append("".join(self.chunks)) + self.chunks.clear() + self.chunks.append(" " * self.indent) + + def render_type(self, type: Type, default: _t.Any): + if default is UNKNOWN: + default = type.default + if isinstance(type, Object): + if not isinstance(default, dict): + default = {} + self.chunks.append("{") + sep = "" + with self.indented(): + for name, type in type.named_children.items(): + if name.startswith("$") or not self.filter(type): + continue + self.chunks.append(sep) + self.newline() + self.chunks.append(json.dumps(name)) + self.chunks.append(": ") + self.render_type(type, default.get(name, type.default)) + sep = "," + if sep: + self.newline() + self.chunks.append("}") + elif isinstance(type, Ref): + self.render_type(self.loader.load(type.ref), default) + elif default is not UNKNOWN: + self.chunks.append(json.dumps(default)) + elif type.const is not UNKNOWN: + self.chunks.append(json.dumps(type.const)) + elif isinstance(type, Array): + self.chunks.append("[]") + elif isinstance(type, Set): + self.chunks.append("[]") + elif isinstance(type, Tuple): + self.chunks.append("[]") + elif isinstance(type, Null): + self.chunks.append("null") + elif isinstance(type, Boolean): + self.chunks.append("false") + elif isinstance(type, Integer): + self.chunks.append("0") + elif isinstance(type, Number): + self.chunks.append("0.0") + elif isinstance(type, String): + self.chunks.append('""') + else: + self.chunks.append("null") + + def filter(self, type: Type) -> bool: + match self.options.get("kind", "all"): + case "user": + return type.has_user_settings + case "project": + return type.has_project_settings + case _: + return True diff --git a/docs/v2/source/_extensions/emmyrc/domain.py b/docs/v2/source/_extensions/emmyrc/domain.py new file mode 100644 index 000000000..61bc7a4d0 --- /dev/null +++ b/docs/v2/source/_extensions/emmyrc/domain.py @@ -0,0 +1,387 @@ +from __future__ import annotations + +import re +import typing as _t +import urllib.parse + +from docutils.parsers.rst import directives +from docutils import nodes +from docutils.nodes import Element, Node +from sphinx import addnodes +from sphinx.addnodes import desc_signature, pending_xref +from sphinx.builders import Builder +from sphinx.directives import ObjectDescription +from sphinx.domains import Domain, ObjType +from sphinx.environment import BuildEnvironment +from sphinx.locale import _, __ +from sphinx.roles import XRefRole +from sphinx.util import logging +from sphinx.util.nodes import make_id, make_refnode + +logger = logging.getLogger("emmyrc") + + +_TYPE_PARSE_RE = re.compile( + r""" + # Skip spaces, they're not meaningful in this context. + \s+ + | + (?P[.]{3}) + | + # Literal string with escapes. + # Example: `"foo"`, `"foo-\"-bar"`. + (?P(?P['"`])(?:\\.|[^\\])*?(?P=string_q)) + | + # Number with optional exponent. + # Example: `1.0`, `.1`, `1.`, `1e+5`. + (?P(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?) + | + # Built-in type. + # Example: `string`, `string?`. + (?Pnull|true|false|boolean|integer|number|string|any|never|object|set|array)\b + \s*(?P\??)\s* + | + # Name component. + (?P\w[\w.#-]*) + | + # Punctuation that we separate with spaces. + (?P[=:,|&]) + | + # Punctuation that we copy as-is, without adding spaces. + (?P[-!#$%()*+/;<>?@[\]^_{}~]+) + | + # Anything else is copied as-is. + (?P.) + """, + re.VERBOSE, +) + + +def type_to_nodes(typ: str, inliner) -> list[nodes.Node]: + res = [] + + for match in _TYPE_PARSE_RE.finditer(typ): + if text := match.group("dots"): + res.append(addnodes.desc_sig_name(text, text)) + elif text := match.group("string"): + res.append(addnodes.desc_sig_literal_string(text, text)) + elif text := match.group("number"): + res.append(addnodes.desc_sig_literal_number(text, text)) + elif text := match.group("type"): + res.append(addnodes.desc_sig_keyword_type(text, text)) + if qm := match.group("type_qm"): + res.append(addnodes.desc_sig_punctuation(qm, qm)) + elif text := match.group("name"): + ref_nodes, warn_nodes = EmmyRcXRefRole()( + "emmyrc:_auto", text, text, 0, inliner + ) + res.extend(ref_nodes) + res.extend(warn_nodes) + elif text := match.group("punct"): + if text in "=|&": + res.append(addnodes.desc_sig_space()) + res.append(addnodes.desc_sig_punctuation(text, text)) + res.append(addnodes.desc_sig_space()) + elif text := match.group("other_punct"): + res.append(addnodes.desc_sig_punctuation(text, text)) + elif text := match.group("other"): + res.append(nodes.Text(text)) + + return res + + +def make_anchor(name: str) -> str: + return urllib.parse.quote(name) + + +class EmmyRcObject(ObjectDescription[tuple[str, str]]): + option_spec = { + "hide-prefix": directives.flag, + **ObjectDescription.option_spec, + } + + def get_display_prefix(self) -> list[Node]: + return [] + + def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]: + sig = sig.replace("/$defs/", "").strip() + + prefix = self.env.ref_context.get("emmyrc:object", "") + + if self.objtype == "property": + member_prefix, member_name, sym, tail = "", sig, "", "" + else: + if ":" in sig or "=" in sig: + member, sym, tail = re.split(r"([:=])", sig, maxsplit=1) + else: + member, sym, tail = sig, "", "" + member = member.strip() + tail = tail.strip() + + try: + member_prefix, member_name = member.rsplit(".", 1) + except ValueError: + member_name = member + member_prefix = "" + if prefix and member_prefix: + prefix = f"{prefix}.{member_prefix}" + elif member_prefix: + prefix = member_prefix + + if prefix: + fullname = f"{prefix}.{member_name}" + else: + fullname = member_name + + signode["object"] = prefix + signode["fullname"] = fullname + + display_prefix = self.get_display_prefix() + if display_prefix: + signode += addnodes.desc_annotation("", "", *display_prefix) + + if member_prefix and "hide-prefix" not in self.options: + add_name = addnodes.desc_addname("", "") + for p in member_prefix.split("."): + add_name += addnodes.desc_sig_name(p, p) + add_name += addnodes.desc_sig_punctuation(".", ".") + signode += add_name + if self.objtype == "property": + signode += addnodes.desc_name( + "", "", *type_to_nodes(member_name, self.state.inliner) + ) + else: + signode += addnodes.desc_name( + "", "", addnodes.desc_sig_name(member_name, member_name) + ) + if type: + if sym == "=": + signode += addnodes.desc_sig_space() + signode += addnodes.desc_sig_punctuation(sym, sym) + signode += addnodes.desc_sig_space() + signode += addnodes.desc_type( + "", "", *type_to_nodes(tail, self.state.inliner) + ) + return fullname, prefix + + def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]: + if "fullname" not in sig_node: + return () + return tuple(sig_node["fullname"].split(".")) + + def add_target_and_index( + self, name_obj: tuple[str, str], sig: str, signode: desc_signature + ) -> None: + fullname = name_obj[0] + anchor = make_anchor(fullname) + + if anchor not in self.state.document.ids: + signode["names"].append(anchor) + signode["ids"].append(anchor) + signode["first"] = not self.names + self.state.document.note_explicit_target(signode) + + domain = self.env.domains["emmyrc"] + assert isinstance(domain, EmmyRcDomain) + domain.note_object(fullname, self.objtype, anchor, location=signode) + + if "no-index-entry" not in self.options: + if index_text := self.get_index_text("", name_obj): + self.indexnode["entries"].append( + ( + "single", + index_text, + anchor, + "", + None, + ) + ) + + def get_index_text(self, objectname: str, name_obj: tuple[str, str]) -> str: + name, obj = name_obj + if obj: + return _("%s (%s attribute)") % (name, obj) + else: + return _("%s (global variable or constant)") % name + + def before_content(self) -> None: + if self.names: + fullname, _ = self.names[-1] + objects = self.env.ref_context.setdefault("emmyrc:objects", []) + objects.append(self.env.ref_context.get("emmyrc:object")) + if fullname: + self.env.ref_context["emmyrc:object"] = fullname + else: + self.env.ref_context.pop("emmyrc:object", None) + + def after_content(self) -> None: + if self.names: + objects = self.env.ref_context.setdefault("emmyrc:objects", []) + if objects: + self.env.ref_context["emmyrc:object"] = objects.pop() + else: + self.env.ref_context.pop("emmyrc:object", None) + + def _toc_entry_name(self, sig_node: desc_signature) -> str: + if not sig_node.get("_toc_parts"): + return "" + + config = self.config + *parents, name = sig_node["_toc_parts"] + if config.toc_object_entries_show_parents == "domain": + return sig_node.get("fullname", name) + if config.toc_object_entries_show_parents == "hide": + return name + if config.toc_object_entries_show_parents == "all": + return ".".join([*parents, name]) + return "" + + +class EmmyRcXRefRole(XRefRole): + def process_link( + self, + env: BuildEnvironment, + refnode: Element, + has_explicit_title: bool, + title: str, + target: str, + ) -> tuple[str, str]: + refnode["emmyrc:object"] = env.ref_context.get("emmyrc:object") + if not has_explicit_title: + title = title.lstrip(".") + target = target.lstrip("~") + if title[0:1] == "~": + title = title[1:] + dot = title.rfind(".") + if dot != -1: + title = title[dot + 1 :] + if target[0:1] == ".": + target = target[1:] + refnode["refspecific"] = True + return title, target + + +class EmmyRcDomain(Domain): + name = "emmyrc" + label = "EmmyLua Config" + object_types = { + "object": ObjType(_("object"), "obj", "_auto"), + "property": ObjType(_("property"), "obj", "_auto"), + } + directives = { + "object": EmmyRcObject, + "property": EmmyRcObject, + } + roles = { + "obj": EmmyRcXRefRole(), + "_auto": EmmyRcXRefRole(), + } + initial_data: dict[str, dict[str, tuple[str, str]]] = { + "objects": {}, # fullname -> docname, node_id, objtype + } + + @property + def objects(self) -> dict[str, tuple[str, str, str]]: + # fullname -> docname, node_id, objtype + return self.data.setdefault("objects", {}) + + def note_object( + self, fullname: str, objtype: str, node_id: str, location: _t.Any = None + ) -> None: + if fullname in self.objects: + docname = self.objects[fullname][0] + logger.warning( + __("duplicate %s description of %s, other %s in %s"), + objtype, + fullname, + objtype, + docname, + location=location, + ) + self.objects[fullname] = (self.env.docname, node_id, objtype) + + def clear_doc(self, docname: str) -> None: + for fullname, (pkg_docname, _node_id, _l) in list(self.objects.items()): + if pkg_docname == docname: + del self.objects[fullname] + + def merge_domaindata( + self, docnames: set[str], otherdata: dict[str, _t.Any] + ) -> None: + for fullname, (fn, node_id, objtype) in otherdata["objects"].items(): + if fn in docnames: + self.objects[fullname] = (fn, node_id, objtype) + + def find_obj( + self, + env: BuildEnvironment, + prefix: str, + name: str, + typ: str | None, + searchorder: int = 0, + ) -> tuple[str | None, tuple[str, str, str] | None]: + searches = [] + if prefix: + searches.append(f"{prefix}.{name}") + searches.append(name) + + if searchorder == 0: + searches.reverse() + + newname = None + object = None + for search_name in searches: + if search_name in self.objects: + newname = search_name + object = self.objects[search_name] + + return newname, object + + def resolve_xref( + self, + env: BuildEnvironment, + fromdocname: str, + builder: Builder, + typ: str, + target: str, + node: pending_xref, + contnode: Element, + ) -> nodes.reference | None: + prefix = node.get("emmyrc:object") + searchorder = 1 if node.hasattr("refspecific") else 0 + name, obj = self.find_obj(env, prefix, target, typ, searchorder) + if not obj: + return None + return make_refnode(builder, fromdocname, obj[0], obj[1], contnode, name) + + def resolve_any_xref( + self, + env: BuildEnvironment, + fromdocname: str, + builder: Builder, + target: str, + node: pending_xref, + contnode: Element, + ) -> list[tuple[str, nodes.reference]]: + prefix = node.get("emmyrc:object") + name, obj = self.find_obj(env, prefix, target, None, 1) + if not obj: + return [] + return [ + ( + f"emmyrc:{self.role_for_objtype(obj[2])}", + make_refnode(builder, fromdocname, obj[0], obj[1], contnode, name), + ) + ] + + def get_objects(self) -> _t.Iterator[tuple[str, str, str, str, str, int]]: + for refname, (docname, node_id, typ) in list(self.objects.items()): + yield refname, refname, typ, docname, node_id, 1 + + def get_full_qualified_name(self, node: Element) -> str | None: + prefix = node.get("emmyrc:object") + target = node.get("reftarget") + if target is None: + return None + else: + return ".".join(filter(None, [prefix, target])) diff --git a/docs/v2/source/_extensions/emmyrc/loader.py b/docs/v2/source/_extensions/emmyrc/loader.py new file mode 100644 index 000000000..43ae14fac --- /dev/null +++ b/docs/v2/source/_extensions/emmyrc/loader.py @@ -0,0 +1,603 @@ +from __future__ import annotations + +import contextlib +import dataclasses +import json +import pathlib +import typing as _t +from dataclasses import dataclass +from urllib.parse import urldefrag, urljoin + +import referencing +import sphinx.application +from frozendict import deepfreeze, frozendict, register as deepfreeze_register +from sphinx.locale import _ + + +class Unknown: + def __bool__(self): + return False + + +UNKNOWN = Unknown() +deepfreeze_register(Unknown, lambda _: UNKNOWN) + + +@dataclass(frozen=True, kw_only=True) +class Type: + id: str = dataclasses.field(default="", compare=False, hash=False) + title: str | None = dataclasses.field(default=None, compare=False, hash=False) + description: str | None = dataclasses.field(default=None, compare=False, hash=False) + deprecated: bool = dataclasses.field(default=False, compare=False, hash=False) + required: bool = dataclasses.field(default=False, compare=False, hash=False) + default: _t.Any | Unknown = dataclasses.field( + default=UNKNOWN, compare=False, hash=False + ) + has_user_settings: bool = dataclasses.field( + default=False, compare=False, hash=False + ) + has_project_settings: bool = dataclasses.field( + default=False, compare=False, hash=False + ) + const: _t.Any | Unknown = UNKNOWN + + def __str__(self) -> str: + raise NotImplementedError("use `print` instead") + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + raise NotImplementedError("override `print` in subclass") + + def unwrap_optional(self) -> Type: + return self + + def is_optional(self) -> bool: + return False + + def find_refs(self) -> list[Ref]: + return [] + + def can_inline(self) -> bool: + return True + + +@dataclass(frozen=True, kw_only=True) +class Object(Type): + properties: Type | None = None + named_children: frozendict[str, Type] = dataclasses.field( + default_factory=lambda: frozendict() + ) + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + items = ", ".join( + f"{name!r}: {ch.print(loader)}" for name, ch in self.named_children.items() + ) + if items: + return f"{{{items}}}" + elif self.properties: + return f"{{string: {self.properties.print(loader)}}}" + else: + return "{}" + + def find_refs(self) -> list[Ref]: + res = [ref for ch in self.named_children.values() for ref in ch.find_refs()] + if self.properties: + res.extend(self.properties.find_refs()) + return res + + +@dataclass(frozen=True) +class Ref(Type): + ref: str + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + if not loader: + return self.ref + + try: + type = loader.load(self.ref) + except Exception: + return self.ref + if loader.can_inline(self.ref): + return type.print(loader, _parens) + else: + return self.ref + + def find_refs(self) -> list[Ref]: + return [self] + + +@dataclass(frozen=True) +class Array(Type): + item: Type + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return f"{self.item.print(loader, True)}[]" + + def find_refs(self) -> list[Ref]: + return self.item.find_refs() + + +@dataclass(frozen=True) +class Set(Type): + item: Type + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return f"{self.item.print(loader, True)}[]" + + def find_refs(self) -> list[Ref]: + return self.item.find_refs() + + +@dataclass(frozen=True) +class Tuple(Type): + items: tuple[Type, ...] + tail: Type | None + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + items = ", ".join(item.print(loader, False) for item in self.items) + if self.tail: + if items: + items += ", " + items += str(self.tail) + "..." + return f"[{items}]" + + def find_refs(self) -> list[Ref]: + res = [ref for ch in self.items for ref in ch.find_refs()] + if self.tail: + res.extend(self.tail.find_refs()) + return res + + +@dataclass(frozen=True) +class Null(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "null" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class Boolean(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "boolean" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class Integer(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "integer" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class Number(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "number" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class String(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "string" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class Any(Type): + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + return "any" if self.const is UNKNOWN else json.dumps(self.const) + + +@dataclass(frozen=True) +class OneOf(Type): + items: tuple[Type, ...] + contains_null: bool = False + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + items = ( + " | ".join( + item.print(loader, True) + for item in self.items + if not isinstance(item, Null) + ) + or "never" + ) + + if self.contains_null and len(self.items) > 2: + return f"({items})?" + elif self.contains_null: + return f"{items}?" + elif _parens: + return f"({items})" + else: + return items + + def unwrap_optional(self) -> Type: + if self.is_optional(): + for item in self.items: + if not isinstance(item, Null): + return item.unwrap_optional() + return self + + def is_optional(self) -> bool: + return self.contains_null and len(self.items) == 2 + + @staticmethod + def create(types: _t.Iterable[Type]) -> Type: + flat = [] + for type in types: + if isinstance(type, OneOf): + flat.extend(type.items) + else: + flat.append(type) + result_set = set() + for type in flat: + if ( + isinstance(type, (Null, Boolean, Integer, Number, String, Any)) + and type.const is not UNKNOWN + ): + result_set.add(dataclasses.replace(type, const=UNKNOWN)) + result: list[Type] = [] + contains_null = False + for type in flat: + if isinstance(type, Null): + contains_null = True + if type in result_set: + continue + result.append(type) + result_set.add(type) + has_user_settings = any(type.has_user_settings for type in result) + has_project_settings = any(type.has_project_settings for type in result) + if len(result) == 1: + return dataclasses.replace( + result[0], + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + elif all(item.const is not UNKNOWN for item in result): + return Enum( + items=tuple(result), + contains_null=contains_null, + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + else: + return OneOf( + items=tuple(result), + contains_null=contains_null, + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + + def find_refs(self) -> list[Ref]: + return [ref for ch in self.items for ref in ch.find_refs()] + + +@dataclass(frozen=True) +class Enum(OneOf): + pass + + +@dataclass(frozen=True) +class AllOf(Type): + items: tuple[Type, ...] + + def print(self, loader: Loader | None = None, _parens: bool = False) -> str: + res = " & ".join(item.print(loader, True) for item in self.items) or "never" + if _parens: + return f"({res})" + else: + return res + + @staticmethod + def create(types: _t.Iterable[Type]) -> Type: + flat = [] + for type in types: + if isinstance(type, AllOf): + flat.extend(type.items) + else: + flat.append(type) + result_set = set() + result: list[Type] = [] + for type in flat: + if type in result_set: + continue + result.append(type) + result_set.add(type) + has_user_settings = any(type.has_user_settings for type in result) + has_project_settings = any(type.has_project_settings for type in result) + if len(result) == 1: + return dataclasses.replace( + result[0], + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + else: + return AllOf( + items=tuple(result), + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + + def find_refs(self) -> list[Ref]: + return [ref for ch in self.items for ref in ch.find_refs()] + + +class Loader: + def __init__( + self, + registry: referencing.Registry[dict[str, _t.Any]], + ): + self._registry = registry + self._base_uris: list[str] = [""] + self._cache: dict[str, Type] = {} + self._ref_count: dict[str, int] = {} + + @property + def _base_uri(self) -> str: + return self._base_uris[-1] + + @contextlib.contextmanager + def _push_base_uri(self, uri: str): + self._base_uris.append(uri) + try: + yield + finally: + self._base_uris.pop() + + def load(self, uri: str) -> Type: + if uri.startswith("#"): + uri, fragment = self._base_uri, uri[1:] + else: + uri, fragment = urldefrag(urljoin(self._base_uri, uri)) + + retrieved = self._registry.get_or_retrieve(uri) + new_uri = retrieved.value.id() or uri + id = new_uri + if fragment: + id += "#" + fragment + + if id not in self._cache: + self._ref_count[id] = 0 + if fragment.startswith("/"): + resolver = self._registry.resolver(new_uri) + resolved = retrieved.value.pointer(pointer=fragment, resolver=resolver) + assert resolver is resolved.resolver, ( + "accessing sub-resources via pointers from base resource " + "is not supported; use resource URI instead" + ) + contents = resolved.contents + elif fragment: + retrieved = retrieved.registry.anchor(uri, fragment) + resolver = self._registry.resolver(new_uri) + resolved = retrieved.value.resolve(resolver=resolver) + assert resolver is resolved.resolver, ( + "accessing sub-resources via pointers from base resource " + "is not supported; use resource URI instead" + ) + contents = resolved.contents + else: + contents = retrieved.value.contents + with self._push_base_uri(new_uri): + self._cache[id] = dataclasses.replace( + self._load_type(contents), + id=id, + ) + + return self._cache[id] + + def can_inline(self, id: str) -> bool: + if not id: + return True + type = self.load(id) + return self._ref_count[id] <= 1 and type.can_inline() + + def get_all_loaded(self) -> list[tuple[str, Type]]: + return sorted(self._cache.items()) + + def _load_type(self, root: dict[str, _t.Any]) -> Type: + if not isinstance(root, dict): + return Any() + + if "$ref" in root: + type = self.load(root["$ref"]) + self._ref_count[type.id] = self._ref_count.get(type.id, 0) + 1 + return Ref( + type.id, + title=root.get("title", None), + description=root.get("description", None), + deprecated=root.get("deprecated", False), + default=root.get("default", UNKNOWN), + has_user_settings=type.has_user_settings, + has_project_settings=type.has_project_settings, + ) + + if "type" not in root: + types = [] + elif not isinstance(root["type"], list): + types = [root["type"]] + else: + types = root["type"] + + result_types: list[Type] = [] + + for type in types: + match type: + case "array": + item = self._load_type(root.get("items", {})) + if "prefixItems" in root: + items = [ + self._load_type(prefix) for prefix in root["prefixItems"] + ] + + if isinstance(max_items := root.get("maxItems", None), int): + if max_items <= len(items): + # Tail is not allowed. + item = None + + return Tuple( + items=tuple(items), + tail=item, + has_user_settings=( + any(item.has_user_settings for item in items) + or (item is not None and item.has_user_settings) + ), + has_project_settings=( + any(item.has_project_settings for item in items) + or (item is not None and item.has_project_settings) + ), + ) + elif root.get("uniqueItems", False): + result_types.append( + Set( + item=item, + has_user_settings=item.has_user_settings, + has_project_settings=item.has_project_settings, + ) + ) + else: + result_types.append( + Array( + item=item, + has_user_settings=item.has_user_settings, + has_project_settings=item.has_project_settings, + ) + ) + case "object": + result_types.append(self._load_object(root)) + case "null": + result_types.append(Null()) + case "boolean": + result_types.append(Boolean()) + case "integer": + result_types.append(Integer()) + case "number": + result_types.append(Number()) + case "string": + result_types.append(String()) + case True: + result_types.append(Any()) + case _: + pass + + if one_of := root.get("anyOf", []): + result_types.extend(self._load_type(type) for type in one_of) + if one_of := root.get("oneOf", []): + result_types.extend(self._load_type(type) for type in one_of) + if enum := root.get("enum", []): + for item in enum: + result_types.append(self.load_const(item)) + + if result_types: + result_types = [OneOf.create(result_types)] + else: + result_types = [] + + if all_of := root.get("allOf", []): + result_types.extend(self._load_type(type) for type in all_of) + + if result_types: + result = AllOf.create(result_types) + else: + result = Any() + + return dataclasses.replace( + result, + title=root.get("title", None), + description=root.get("description", None), + deprecated=root.get("deprecated", False), + default=root.get("default", UNKNOWN), + const=deepfreeze(root.get("const", UNKNOWN)), + has_user_settings=result.has_user_settings, + has_project_settings=result.has_project_settings, + ) + + def _load_object(self, root: dict[str, _t.Any]) -> Type: + # This code repeats implementation of `Resolver.lookup`, + # see https://github.com/python-jsonschema/referencing/issues/257 + if not isinstance(root.get("default", UNKNOWN), dict): + default = {} + else: + default = root["default"] + if not isinstance(root.get("properties", None), dict): + properties = {} + else: + properties = root["properties"] + if not isinstance(root.get("required", None), list): + required = set() + else: + required = set(root["required"]) + + children = {} + for name, data in properties.items(): + child = self._load_type(data) + + if "x-vscode-setting" in data: + has_user_settings = True + has_project_settings = False + else: + has_user_settings = child.has_user_settings + has_project_settings = child.has_project_settings + if not has_project_settings and not has_user_settings: + has_project_settings = True + + child = dataclasses.replace( + child, + default=default.get(name, child.default), + required=name in required, + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + children[name] = child + + if "additionalProperties" in root: + properties = self._load_type(root["additionalProperties"]) + else: + properties = None + + has_user_settings = any( + type.has_user_settings for type in children.values() + ) or (properties is not None and properties.has_user_settings) + has_project_settings = any( + type.has_project_settings for type in children.values() + ) or (properties is not None and properties.has_project_settings) + + return Object( + title=root.get("title", None), + description=root.get("description", None), + deprecated=root.get("deprecated", False), + named_children=frozendict(children), + properties=properties, + has_user_settings=has_user_settings, + has_project_settings=has_project_settings, + ) + + def load_const(self, value: _t.Any): + if value is None: + return Null() + elif isinstance(value, bool): + return Boolean(const=value) + elif isinstance(value, int): + return Integer(const=value) + elif isinstance(value, float): + return Number(const=value) + elif isinstance(value, str): + return String(const=value) + else: + return Any(const=deepfreeze(value)) + + +def split_uri(base: str, uri: str) -> tuple[str, str]: + if "#" in uri: + uri, anchor = uri.split("#", maxsplit=1) + else: + anchor = "" + return uri or base, "#" + anchor + + +def load_jsons(app: sphinx.application.Sphinx): + path = pathlib.Path(app.srcdir, app.config["emmylua_schema"]).expanduser().resolve() + return ( + referencing.Registry() + .with_resource( + "EmmyRc", + referencing.Resource.from_contents(json.loads(path.read_text())), + ) + .crawl() + ) diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/annotations/index.po b/docs/v2/source/_locales/zh/LC_MESSAGES/annotations/index.po new file mode 100644 index 000000000..7f6126f57 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/annotations/index.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/annotations/index.md:1 +msgid "Annotations" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/configuration.po b/docs/v2/source/_locales/zh/LC_MESSAGES/configuration.po new file mode 100644 index 000000000..ebdee4556 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/configuration.po @@ -0,0 +1,777 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/configuration.md:1 +msgid "Configuration" +msgstr "" + +#: ../../source/configuration.md:3 +msgid "" +"EmmyLua loads settings from `.emmyrc.json` located in project's root. For" +" settings that aren't listed in project's `.emmyrc.json`, EmmyLua will " +"search for user-specific defaults." +msgstr "" + +#: ../../source/configuration.md:7 +msgid "Compatibility with LuaLs" +msgstr "" + +#: ../../source/configuration.md:9 +msgid "" +"If your project uses LuaLs, EmmyLua will be able to extract some settings" +" from `.luarc.json`. However, `.emmyrc.json` configuration format is more" +" feature-rich, and incompatible parts will be automatically ignored." +msgstr "" + +#: ../../source/configuration.md:13 +msgid "Project settings" +msgstr "" + +#: ../../source/configuration.md:15 +msgid "" +"Create an `.emmyrc.json` in the root directory of your project. At the " +"minimum, you'll want to configure Lua runtime version:" +msgstr "" + +#: ../../source/configuration.md:26 +msgid "" +"To kick-start configuration process you can use this template. It " +"contains all project-specific settings along with their default values:" +msgstr "" + +#: ../../source/configuration.md:29 +msgid "A template for project-specific `.emmyrc.json`" +msgstr "" + +#: ../../source/configuration.md:37 +msgid "Tip" +msgstr "" + +#: ../../source/configuration.md:38 +msgid "" +"Only add project-specific setting to your project's `.emmyrc.json`. For " +"example, it's a good idea to set up [Lua " +"version](#EmmyRc.runtime.version) or [naming convention for auto-" +"required paths](#EmmyRc.completion.autoRequireNamingConvention), but " +"overriding [settings for inlay hints](#EmmyRc.hint) would serve no " +"purpose." +msgstr "" + +#: ../../source/configuration.md:45 +msgid "User settings" +msgstr "" + +#: ../../source/configuration.md:47 +msgid "" +"You can override default settings by creating an `.emmyrc.json` in your " +"home or config directory." +msgstr "" + +#: ../../source/configuration.md:50 +msgid "Here's a full list of places where EmmyLua will look" +msgstr "" + +#: ../../source/configuration.md:53 +msgid "local `.emmyrc.json`: a JSON file located in your project's root," +msgstr "" + +#: ../../source/configuration.md:54 +msgid "local `.luarc.json`: a JSON file located in your project's root," +msgstr "" + +#: ../../source/configuration.md:55 +msgid "a JSON file specified by environment variable `$EMMYLUALS_CONFIG`," +msgstr "" + +#: ../../source/configuration.md:56 +msgid "global `/emmylua_ls/.emmyrc.json`," +msgstr "" + +#: ../../source/configuration.md:57 +msgid "global `/emmylua_ls/.luarc.json`," +msgstr "" + +#: ../../source/configuration.md:58 +msgid "global `/.emmyrc.json`," +msgstr "" + +#: ../../source/configuration.md:59 +msgid "global `/.luarc.json`." +msgstr "" + +#: ../../source/configuration.md:61 +msgid "Depending on your platform, `` will be different:" +msgstr "" + +#: ../../source/configuration.md:70 +msgid "" +"Additionally, some editors allow overriding project's config values. See " +"[installation instructions](installation) for details." +msgstr "" + +#: ../../source/configuration.md:73 +msgid "" +"To kick-start configuration process you can use this template. It " +"contains all user-specific settings along with their default values:" +msgstr "" + +#: ../../source/configuration.md:76 +msgid "A template for user-specific `.emmyrc.json`" +msgstr "" + +#: ../../source/configuration.md:84 +msgid "Schema" +msgstr "" + +#: ../../source/configuration.md:86 +msgid "" +"To enable intelligent completion and validation for configuration files, " +"you can add a schema reference to your configuration file:" +msgstr "" + +#: ../../source/configuration.md:95 +msgid "Full list of config values" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for code actions and quick fixes." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Add space after `---` comments when inserting `@diagnostic disable-next-" +"line`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for code lens features." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable code lens." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for code completion features." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"When enabled, selecting a completion suggestion from another module will " +"add the appropriate require statement." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Name of the function that's inserted when auto-requiring modules." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"Default is `\"require\"`, but can be customized to use any module loader " +"function." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "The naming convention for auto-required filenames." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"Controls how the imported module names are formatted in the `require` " +"statement." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Keep the original filename without any transformation." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `\"my-module\"` remains `\"my-module\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Convert the filename to `snake_case`." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `\"MyModule\"` becomes `\"my_module\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Convert the filename to `PascalCase`." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `\"my_module\"` becomes `\"MyModule\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Convert the filename to `camelCase`." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `\"my_module\"` becomes `\"myModule\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"When returning a class definition, use the class name; otherwise keep the" +" original name." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"This is useful for modules that export a single class with a name that " +"might differ from the filename." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Defines the character used to separate path segments in require " +"statements." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Default is `\".\"`, but can be changed to other separators like `\"/\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Whether to include the name in the base function in postfix " +"autocompletion." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Effect: `function () end` -> `function name() end`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Whether to use call snippets in completions." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"When enabled, function completions will insert a snippet with " +"placeholders for function arguments, allowing for quick tabbing between " +"parameters." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable autocompletion." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Symbol that's used to trigger postfix autocompletion." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for diagnostics and error detection." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Delay between opening/changing a file and scanning it for errors, in " +"milliseconds." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A list of suppressed diagnostics." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A flag indicating whether diagnostics are enabled at all." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A list of diagnostic codes that are enabled, in addition to default ones." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A list of global variables." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Variables from this list are always treated as defined globals." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A list of regular expressions for global variables." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"Variables that match these regular expressions are always treated as " +"defined globals." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "A map of diagnostic codes to their severity settings." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Represents an error diagnostic severity." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Represents a warning diagnostic severity." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Represents an information diagnostic severity." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Represents a hint diagnostic severity." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for documentation parsing." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of known documentation tags." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"List of glob patterns that enable treating specific field names as " +"private." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"For example, `m_*` would make fields `Type.m_id` and `Type.m_type` " +"private." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"When `syntax` is `Myst` or `Rst`, specifies [default role] used with RST " +"processor." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"When `syntax` is `Myst` or `Rst`, specifies [primary domain] used with " +"RST processor." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Syntax for highlighting documentation." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Documentation is not highlighted." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Documentation is highlighted as plain [MarkDown]." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Documentation is highlighted as [MySt], a MarkDown plugin for [Sphinx]." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Enables Autocompletion and Go To Definition for sphinx cross-references." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Documentation is highlighted as [ReStructured Text]." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Enables Autocompletion and Go To Definition for [sphinx] cross-references." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for document color features." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Enable parsing strings for color tags and showing a color picker next to " +"them." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for code formatting." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for external formatting tool." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of arguments to pass to the external tool." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Each argument can contain the following patterns:" +msgstr "" + +#: ../../source/configuration.md:102 +#, python-brace-format +msgid "`${file}` expands to the file path that needs formatting;" +msgstr "" + +#: ../../source/configuration.md:104 +#, python-brace-format +msgid "`${indent_size}` expands to numeric value for indentation size;" +msgstr "" + +#: ../../source/configuration.md:106 +#, python-brace-format +msgid "" +"`${use_tabs?:}` expands to `` placeholder or " +"`` placeholder depending on whether tabs are used for indentation." +msgstr "" + +#: ../../source/configuration.md:110 +#, python-brace-format +msgid "" +"For example, `${use_tabs?--tabs}` will expand to `--tabs` if tabs are " +"required, or an empty string if tabs are not required." +msgstr "" + +#: ../../source/configuration.md:113 +#, python-brace-format +msgid "" +"`${insert_final_newline?:}` expands to `` " +"placeholder or `` placeholder depending on whether the tool should" +" insert final newline." +msgstr "" + +#: ../../source/configuration.md:117 +#, python-brace-format +msgid "" +"`${non_standard_symbol?:}` expands to `` " +"placeholder or `` placeholder depending on whether non-standard " +"symbols are enabled." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "The command to run the external tool." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Command timeout, in milliseconds." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Whether to use the diff algorithm for formatting." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for inlay hints in the editor." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable inlay hints." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Show name of enumerator when passing a literal value to a function that " +"expects an enum." +msgstr "" + +#: ../../source/configuration.md:100 ../../source/configuration.md:101 +#: ../../source/configuration.md:107 +msgid "Example:" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Show named array indexes." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Show types of local variables." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Show hint when calling an object results in a call to its meta table's " +"`__call` function." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Show methods that override functions from base class." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Show parameter names in function calls and parameter types in function " +"definitions." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for hover information." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable showing documentation on hover." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for inline value display." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Show inline values during debug." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for reference lookup features." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable searching for symbol usages." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Use fuzzy search when searching for symbol usages and normal search " +"didn't find anything." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Also search for usages in strings." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for resource file management." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"List of resource directories used in a project. Files from these " +"directories will be added to autocompletion when completing file paths." +msgstr "" + +#: ../../source/configuration.md:102 +msgid "" +"This list can contain anything, like directories with game assets, " +"template files, and so on. No special interpretation beyond " +"autocompletion is given to these paths." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for Lua runtime." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Controls resolution of class constructors." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Remove the `self` parameter from list of constructor parameters when " +"inferring constructor signature using `functionName`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Always use `self` as constructor's return type when inferring constructor" +" signature using `functionName`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Name of the method that's used to resolve class default `__call` operator." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "" +"For example, if `functionName` is `\"__init\"`, then EmmyLua will use " +"parameters and return types of `__init` method as parameters and return " +"types of class' `__call` operator:" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Extensions of Lua files that need analysis." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `[\".lua\", \".lua.txt\"]`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of enabled non-standard symbols." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Functions that are treated like `require`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Require pattern in the format of Lua's [`path`]." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `[\"?.lua\", \"?/init.lua\"]`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua version." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua 5.1" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "LuaJIT" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua 5.2" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua 5.3" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua 5.4" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua 5.5" +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Lua Latest, currently set to `Lua5.4`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for semantic token highlighting." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable semantic tokens." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Render Markdown/RST in documentation. Set `doc.syntax` for this option to" +" have effect." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for function signature help." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Whether to enable signature help." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for strict type checks." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Whether to enable strict mode when inferring type of array indexing " +"operation." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Base constant types defined in doc can match base types, allowing `int` " +"to match `---@alias id 1|2|3`, same for string." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Definitions from `@meta` files always overrides definitions from normal " +"files." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Whether to enable strict mode for resolving require paths." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Configuration for workspace management." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Enable full project reindex after changing a file." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "File encoding." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of ignored directories." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of globs for ignored files." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of library roots." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `\"/usr/local/share/lua/5.1\"`." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Module map. Allows customizing conversion from file paths to module names" +" and require paths." +msgstr "" + +#: ../../source/configuration.md:101 +msgid "" +"This is a list of objects, each containing a regular expression and a " +"replace string. When generating module name for a file, EmmyLua will " +"reverse-match file path with require patterns, generate an appropriate " +"module name, then run it through these replace patterns to get the final " +"module name." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "" +"Regular expression that will be matched against the generated module " +"name. See [regex] crate for details about syntax." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Replace string. Use `$name` to substitute capturing groups from regex." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "Delay between changing a file and full project reindex, in milliseconds." +msgstr "" + +#: ../../source/configuration.md:98 +msgid "List of workspace roots." +msgstr "" + +#: ../../source/configuration.md:100 +msgid "Example: `[\"src\", \"test\"]`." +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/diagnostics.po b/docs/v2/source/_locales/zh/LC_MESSAGES/diagnostics.po new file mode 100644 index 000000000..1f13f2d61 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/diagnostics.po @@ -0,0 +1,229 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/diagnostics.md:1 +msgid "Diagnostics" +msgstr "" + +#: ../../source/diagnostics.md:3 +#, python-brace-format +msgid "" +"Diagnostics can be suppressed through " +"{emmyrc:obj}`EmmyRc.diagnostics.disable`. You can also change severity of" +" an individual diagnostic with {emmyrc:obj}`EmmyRc.diagnostics.severity`." +msgstr "" + +#: ../../source/diagnostics.md:7 +#, python-brace-format +msgid "" +"Some diagnostics are disabled by default. You can re-enable them by " +"adding their codes to {emmyrc:obj}`EmmyRc.diagnostics.enables`." +msgstr "" + +#: ../../source/diagnostics.md:10 +msgid "Full list of diagnostic codes" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Syntax error" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Doc syntax error" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Type not found" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Missing return statement" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Param Type not match" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Missing parameter" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Redundant parameter" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Unreachable code" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Unused" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Undefined global" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Deprecated" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Access invisible" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Discard return value" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Undefined field" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Local const reassign" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Iter variable reassign" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Duplicate type" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Redefined local" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Redefined label" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Code style check" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Need check nil" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Await in sync" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Doc tag usage error" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Return type mismatch" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Missing return value" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Redundant return value" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Undefined Doc Param" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Duplicate doc field" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Unknown doc annotation" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Missing fields" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Inject Field" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Circle Doc Class" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Incomplete signature doc" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Missing global doc" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Assign type mismatch" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Duplicate require" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "non-literal-expressions-in-assert" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "Unbalanced assignments" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "unnecessary-assert" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "unnecessary-if" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "duplicate-set-field" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "duplicate-index" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "generic-constraint-mismatch" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "cast-type-mismatch" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "require-module-not-visible" +msgstr "" + +#: ../../source/diagnostics.md:14 +msgid "enum-value-mismatch" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/features.po b/docs/v2/source/_locales/zh/LC_MESSAGES/features.po new file mode 100644 index 000000000..fca05cd70 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/features.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/features.md:1 +msgid "Features" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/guide/configuration.po b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/configuration.po new file mode 100644 index 000000000..e4ecedcdc --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/configuration.po @@ -0,0 +1,130 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/guide/configuration.md:1 +msgid "Configuration" +msgstr "" + +#: ../../source/guide/configuration.md:3 +msgid "" +"EmmyLua loads settings from `.emmyrc.json` located in project's root. For" +" settings that aren't listed in project's `.emmyrc.json`, EmmyLua will " +"search for user-specific defaults." +msgstr "" + +#: ../../source/guide/configuration.md:7 ../../source/guide/configuration.md:55 +msgid "See also" +msgstr "" + +#: ../../source/guide/configuration.md:8 +msgid "" +"Full list of configuration values [is available in the reference " +"section](../reference/configuration.md#full-list-of-config-values)." +msgstr "" + +#: ../../source/guide/configuration.md:12 +msgid "Compatibility with LuaLs" +msgstr "" + +#: ../../source/guide/configuration.md:14 +msgid "" +"If your project uses LuaLs, EmmyLua will be able to extract some settings" +" from `.luarc.json`. However, `.emmyrc.json` configuration format is more" +" feature-rich, and incompatible parts will be automatically ignored." +msgstr "" + +#: ../../source/guide/configuration.md:18 +msgid "Project settings" +msgstr "" + +#: ../../source/guide/configuration.md:20 +msgid "" +"Create an `.emmyrc.json` in the root directory of your project. At the " +"minimum, you'll want to configure Lua runtime version:" +msgstr "" + +#: ../../source/guide/configuration.md:31 +msgid "" +"To kick-start configuration process you can use this template. It " +"contains all project-specific settings along with their default values:" +msgstr "" + +#: ../../source/guide/configuration.md:34 +msgid "A template for project-specific `.emmyrc.json`" +msgstr "" + +#: ../../source/guide/configuration.md:42 +msgid "Tip" +msgstr "" + +#: ../../source/guide/configuration.md:43 +msgid "" +"Only add project-specific setting to your project's `.emmyrc.json`. For " +"example, it's a good idea to set up [Lua " +"version](#EmmyRc.runtime.version) or [naming convention for auto-" +"required paths](#EmmyRc.completion.autoRequireNamingConvention), but " +"overriding [settings for inlay hints](#EmmyRc.hint) would serve no " +"purpose." +msgstr "" + +#: ../../source/guide/configuration.md:50 +msgid "User settings" +msgstr "" + +#: ../../source/guide/configuration.md:52 +msgid "" +"You can override default settings by creating an `.emmyrc.json` in your " +"home or config directory." +msgstr "" + +#: ../../source/guide/configuration.md:56 +msgid "" +"Full list of places where EmmyLua searches for configs [is available in" +" the reference section](../reference/configuration.md#loading-order)." +msgstr "" + +#: ../../source/guide/configuration.md:60 +msgid "" +"Additionally, some editors allow overriding project's config values. See " +"[installation instructions](installation) for details." +msgstr "" + +#: ../../source/guide/configuration.md:63 +msgid "" +"To kick-start configuration process you can use this template. It " +"contains all user-specific settings along with their default values:" +msgstr "" + +#: ../../source/guide/configuration.md:66 +msgid "A template for user-specific `.emmyrc.json`" +msgstr "" + +#: ../../source/guide/configuration.md:74 +msgid "Schema" +msgstr "" + +#: ../../source/guide/configuration.md:76 +msgid "" +"To enable intelligent completion and validation for configuration files, " +"you can add a schema reference to your configuration file:" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/guide/features.po b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/features.po new file mode 100644 index 000000000..a580cf296 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/features.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/guide/features.md:1 +msgid "Features" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/guide/index.po b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/index.po new file mode 100644 index 000000000..235cb402e --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/index.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/guide/index.md:1 +msgid "Guide" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/guide/installation.po b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/installation.po new file mode 100644 index 000000000..a1318b553 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/guide/installation.po @@ -0,0 +1,113 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/guide/installation.md:1 +msgid "Installation" +msgstr "" + +#: ../../source/guide/installation.md:3 +msgid "VSCode" +msgstr "" + +#: ../../source/guide/installation.md:5 +msgid "Install the [EmmyLua Extension] for the best development experience." +msgstr "" + +#: ../../source/guide/installation.md:9 +msgid "Intellij Idea" +msgstr "" + +#: ../../source/guide/installation.md:11 +msgid "Install the [EmmyLua2 Plugin] from the JetBrains Marketplace." +msgstr "" + +#: ../../source/guide/installation.md:15 +msgid "NeoVim" +msgstr "" + +#: ../../source/guide/installation.md:17 +msgid "" +"Install EmmyLua to your system using `cargo` (or another method, [see " +"below](#standalone)):" +msgstr "" + +#: ../../source/guide/installation.md:24 +msgid "Install [nvim-lspconfig]." +msgstr "" + +#: ../../source/guide/installation.md:28 +msgid "Enable LSP client in your `init.lua`:" +msgstr "" + +#: ../../source/guide/installation.md:34 +msgid "You can [configure](./configuration.md) EmmyLua via `vim.lsp.config`:" +msgstr "" + +#: ../../source/guide/installation.md:49 +msgid "See [`:help lspconfig-all | /emmylua_ls`][nvim-help] for more info." +msgstr "" + +#: ../../source/guide/installation.md:53 +msgid "Note" +msgstr "" + +#: ../../source/guide/installation.md:54 +msgid "These options will override project-specific `.emmyrc.json`." +msgstr "" + +#: ../../source/guide/installation.md:56 +msgid "" +"For options that control LSP features, this is a desired behavior; for " +"options that control language analysis, it is not." +msgstr "" + +#: ../../source/guide/installation.md:59 +msgid "" +"If you need to alter defaults without overriding project-specific " +"settings, you can do so by creating `.emmyrc.json` in your home or " +"config directory. See [](configuration.md#user-settings) for details." +msgstr "" + +#: ../../source/guide/installation.md:64 +msgid "Standalone" +msgstr "" + +#: ../../source/guide/installation.md:66 +msgid "EmmyLua is available as a standalone executable." +msgstr "" + +#: ../../source/guide/installation.md:68 +msgid "**Via Cargo:**" +msgstr "" + +#: ../../source/guide/installation.md:70 +msgid "[Install Rust and Cargo]." +msgstr "" + +#: ../../source/guide/installation.md:85 +msgid "**Pre-built binaries:**" +msgstr "" + +#: ../../source/guide/installation.md:87 +msgid "Download the latest binaries from our [releases page]." +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/index.po b/docs/v2/source/_locales/zh/LC_MESSAGES/index.po new file mode 100644 index 000000000..33c0aab28 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/index.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/index.md:1 +msgid "EmmyLua Analyzer" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/installation.po b/docs/v2/source/_locales/zh/LC_MESSAGES/installation.po new file mode 100644 index 000000000..7e7cabe4e --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/installation.po @@ -0,0 +1,113 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/installation.md:1 +msgid "Installation" +msgstr "" + +#: ../../source/installation.md:3 +msgid "VSCode" +msgstr "" + +#: ../../source/installation.md:5 +msgid "Install the [EmmyLua Extension] for the best development experience." +msgstr "" + +#: ../../source/installation.md:9 +msgid "Intellij Idea" +msgstr "" + +#: ../../source/installation.md:11 +msgid "Install the [EmmyLua2 Plugin] from the JetBrains Marketplace." +msgstr "" + +#: ../../source/installation.md:15 +msgid "NeoVim" +msgstr "" + +#: ../../source/installation.md:17 +msgid "" +"Install EmmyLua to your system using `cargo` (or another method, [see " +"below](#standalone)):" +msgstr "" + +#: ../../source/installation.md:24 +msgid "Install [nvim-lspconfig]." +msgstr "" + +#: ../../source/installation.md:28 +msgid "Enable LSP client in your `init.lua`:" +msgstr "" + +#: ../../source/installation.md:34 +msgid "You can [configure](settings) EmmyLua via `vim.lsp.config`:" +msgstr "" + +#: ../../source/installation.md:49 +msgid "See [`:help lspconfig-all | /emmylua_ls`][nvim-help] for more info." +msgstr "" + +#: ../../source/installation.md:53 +msgid "Note" +msgstr "" + +#: ../../source/installation.md:54 +msgid "These options will override project-specific `.emmyrc.json`." +msgstr "" + +#: ../../source/installation.md:56 +msgid "" +"For options that control LSP features, this is a desired behavior; for " +"options that control language analysis, it is not." +msgstr "" + +#: ../../source/installation.md:59 +msgid "" +"If you need to alter defaults without overriding project-specific " +"settings, you can do so by creating " +"`$HOME/.config/emmylua_ls/.emmyrc.json`. See [](settings) for details." +msgstr "" + +#: ../../source/installation.md:65 +msgid "Standalone" +msgstr "" + +#: ../../source/installation.md:67 +msgid "EmmyLua is available as a standalone executable." +msgstr "" + +#: ../../source/installation.md:69 +msgid "**Via Cargo:**" +msgstr "" + +#: ../../source/installation.md:71 +msgid "[Install Rust and Cargo]." +msgstr "" + +#: ../../source/installation.md:86 +msgid "**Pre-built binaries:**" +msgstr "" + +#: ../../source/installation.md:88 +msgid "Download the latest binaries from our [releases page]." +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/reference/annotations.po b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/annotations.po new file mode 100644 index 000000000..75a10b80d --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/annotations.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/reference/annotations.md:1 +msgid "Annotations" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/reference/configuration.po b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/configuration.po new file mode 100644 index 000000000..140bc20e1 --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/configuration.po @@ -0,0 +1,754 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/reference/configuration.md:1 +msgid "Configuration" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "See also" +msgstr "" + +#: ../../source/reference/configuration.md:4 +msgid "See our guide on [how to configure EmmyLua](../guide/configuration.md)." +msgstr "" + +#: ../../source/reference/configuration.md:7 +msgid "Loading order" +msgstr "" + +#: ../../source/reference/configuration.md:9 +msgid "" +"EmmyLua will search for configs in the following order. Values from " +"configs higher in the list override values from configs lower in the " +"list:" +msgstr "" + +#: ../../source/reference/configuration.md:12 +msgid "local `.emmyrc.json`: a JSON file located in your project's root," +msgstr "" + +#: ../../source/reference/configuration.md:13 +msgid "local `.luarc.json`: a JSON file located in your project's root," +msgstr "" + +#: ../../source/reference/configuration.md:14 +msgid "a JSON file specified by environment variable `$EMMYLUALS_CONFIG`," +msgstr "" + +#: ../../source/reference/configuration.md:15 +msgid "global `/emmylua_ls/.emmyrc.json`," +msgstr "" + +#: ../../source/reference/configuration.md:16 +msgid "global `/emmylua_ls/.luarc.json`," +msgstr "" + +#: ../../source/reference/configuration.md:17 +msgid "global `/.emmyrc.json`," +msgstr "" + +#: ../../source/reference/configuration.md:18 +msgid "global `/.luarc.json`." +msgstr "" + +#: ../../source/reference/configuration.md:20 +msgid "Depending on your platform, `` will be different:" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "Platform" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "Value" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "Example" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "Linux" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "`$XDG_CONFIG_HOME` or `$HOME/.config`" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "`/home/alice/.config`" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "macOS" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "`$HOME/Library/Application Support`" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "`/Users/Alice/Library/Application Support`" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "Windows" +msgstr "" + +#: ../../source/reference/configuration.md:3 +#, python-brace-format +msgid "`{FOLDERID_RoamingAppData}`" +msgstr "" + +#: ../../source/reference/configuration.md:3 +msgid "`C:\\Users\\Alice\\AppData\\Roaming`" +msgstr "" + +#: ../../source/reference/configuration.md:28 +msgid "Full list of config values" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for code actions and quick fixes." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Add space after `---` comments when inserting `@diagnostic disable-next-" +"line`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for code lens features." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable code lens." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for code completion features." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"When enabled, selecting a completion suggestion from another module will " +"add the appropriate require statement." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Name of the function that's inserted when auto-requiring modules." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"Default is `\"require\"`, but can be customized to use any module loader " +"function." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "The naming convention for auto-required filenames." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"Controls how the imported module names are formatted in the `require` " +"statement." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Keep the original filename without any transformation." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `\"my-module\"` remains `\"my-module\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Convert the filename to `snake_case`." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `\"MyModule\"` becomes `\"my_module\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Convert the filename to `PascalCase`." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `\"my_module\"` becomes `\"MyModule\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Convert the filename to `camelCase`." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `\"my_module\"` becomes `\"myModule\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"When returning a class definition, use the class name; otherwise keep the" +" original name." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"This is useful for modules that export a single class with a name that " +"might differ from the filename." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Defines the character used to separate path segments in require " +"statements." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Default is `\".\"`, but can be changed to other separators like `\"/\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Whether to include the name in the base function in postfix " +"autocompletion." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Effect: `function () end` -> `function name() end`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Whether to use call snippets in completions." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"When enabled, function completions will insert a snippet with " +"placeholders for function arguments, allowing for quick tabbing between " +"parameters." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable autocompletion." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Symbol that's used to trigger postfix autocompletion." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for diagnostics and error detection." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Delay between opening/changing a file and scanning it for errors, in " +"milliseconds." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A list of suppressed diagnostics." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A flag indicating whether diagnostics are enabled at all." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A list of diagnostic codes that are enabled, in addition to default ones." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A list of global variables." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Variables from this list are always treated as defined globals." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A list of regular expressions for global variables." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"Variables that match these regular expressions are always treated as " +"defined globals." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "A map of diagnostic codes to their severity settings." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Represents an error diagnostic severity." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Represents a warning diagnostic severity." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Represents an information diagnostic severity." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Represents a hint diagnostic severity." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for documentation parsing." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of known documentation tags." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"List of glob patterns that enable treating specific field names as " +"private." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"For example, `m_*` would make fields `Type.m_id` and `Type.m_type` " +"private." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"When `syntax` is `Myst` or `Rst`, specifies [default role] used with RST " +"processor." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"When `syntax` is `Myst` or `Rst`, specifies [primary domain] used with " +"RST processor." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Syntax for highlighting documentation." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Documentation is not highlighted." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Documentation is highlighted as plain [MarkDown]." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Documentation is highlighted as [MySt], a MarkDown plugin for [Sphinx]." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Enables Autocompletion and Go To Definition for sphinx cross-references." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Documentation is highlighted as [ReStructured Text]." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Enables Autocompletion and Go To Definition for [sphinx] cross-references." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for document color features." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Enable parsing strings for color tags and showing a color picker next to " +"them." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for code formatting." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for external formatting tool." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of arguments to pass to the external tool." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Each argument can contain the following patterns:" +msgstr "" + +#: ../../source/reference/configuration.md:35 +#, python-brace-format +msgid "`${file}` expands to the file path that needs formatting;" +msgstr "" + +#: ../../source/reference/configuration.md:37 +#, python-brace-format +msgid "`${indent_size}` expands to numeric value for indentation size;" +msgstr "" + +#: ../../source/reference/configuration.md:39 +#, python-brace-format +msgid "" +"`${use_tabs?:}` expands to `` placeholder or " +"`` placeholder depending on whether tabs are used for indentation." +msgstr "" + +#: ../../source/reference/configuration.md:43 +#, python-brace-format +msgid "" +"For example, `${use_tabs?--tabs}` will expand to `--tabs` if tabs are " +"required, or an empty string if tabs are not required." +msgstr "" + +#: ../../source/reference/configuration.md:46 +#, python-brace-format +msgid "" +"`${insert_final_newline?:}` expands to `` " +"placeholder or `` placeholder depending on whether the tool should" +" insert final newline." +msgstr "" + +#: ../../source/reference/configuration.md:50 +#, python-brace-format +msgid "" +"`${non_standard_symbol?:}` expands to `` " +"placeholder or `` placeholder depending on whether non-standard " +"symbols are enabled." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "The command to run the external tool." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Command timeout, in milliseconds." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Whether to use the diff algorithm for formatting." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for inlay hints in the editor." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable inlay hints." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Show name of enumerator when passing a literal value to a function that " +"expects an enum." +msgstr "" + +#: ../../source/reference/configuration.md:33 +#: ../../source/reference/configuration.md:34 +#: ../../source/reference/configuration.md:40 +msgid "Example:" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Show named array indexes." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Show types of local variables." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Show hint when calling an object results in a call to its meta table's " +"`__call` function." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Show methods that override functions from base class." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Show parameter names in function calls and parameter types in function " +"definitions." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for hover information." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable showing documentation on hover." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for inline value display." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Show inline values during debug." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for reference lookup features." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable searching for symbol usages." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Use fuzzy search when searching for symbol usages and normal search " +"didn't find anything." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Also search for usages in strings." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for resource file management." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"List of resource directories used in a project. Files from these " +"directories will be added to autocompletion when completing file paths." +msgstr "" + +#: ../../source/reference/configuration.md:35 +msgid "" +"This list can contain anything, like directories with game assets, " +"template files, and so on. No special interpretation beyond " +"autocompletion is given to these paths." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for Lua runtime." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Controls resolution of class constructors." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Remove the `self` parameter from list of constructor parameters when " +"inferring constructor signature using `functionName`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Always use `self` as constructor's return type when inferring constructor" +" signature using `functionName`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Name of the method that's used to resolve class default `__call` operator." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "" +"For example, if `functionName` is `\"__init\"`, then EmmyLua will use " +"parameters and return types of `__init` method as parameters and return " +"types of class' `__call` operator:" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Extensions of Lua files that need analysis." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `[\".lua\", \".lua.txt\"]`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of enabled non-standard symbols." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Functions that are treated like `require`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Require pattern in the format of Lua's [`path`]." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `[\"?.lua\", \"?/init.lua\"]`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua version." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua 5.1" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "LuaJIT" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua 5.2" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua 5.3" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua 5.4" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua 5.5" +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Lua Latest, currently set to `Lua5.4`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for semantic token highlighting." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable semantic tokens." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Render Markdown/RST in documentation. Set `doc.syntax` for this option to" +" have effect." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for function signature help." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Whether to enable signature help." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for strict type checks." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Whether to enable strict mode when inferring type of array indexing " +"operation." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Base constant types defined in doc can match base types, allowing `int` " +"to match `---@alias id 1|2|3`, same for string." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Definitions from `@meta` files always overrides definitions from normal " +"files." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Whether to enable strict mode for resolving require paths." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Configuration for workspace management." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Enable full project reindex after changing a file." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "File encoding." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of ignored directories." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of globs for ignored files." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of library roots." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `\"/usr/local/share/lua/5.1\"`." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Module map. Allows customizing conversion from file paths to module names" +" and require paths." +msgstr "" + +#: ../../source/reference/configuration.md:34 +msgid "" +"This is a list of objects, each containing a regular expression and a " +"replace string. When generating module name for a file, EmmyLua will " +"reverse-match file path with require patterns, generate an appropriate " +"module name, then run it through these replace patterns to get the final " +"module name." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "" +"Regular expression that will be matched against the generated module " +"name. See [regex] crate for details about syntax." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Replace string. Use `$name` to substitute capturing groups from regex." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "Delay between changing a file and full project reindex, in milliseconds." +msgstr "" + +#: ../../source/reference/configuration.md:31 +msgid "List of workspace roots." +msgstr "" + +#: ../../source/reference/configuration.md:33 +msgid "Example: `[\"src\", \"test\"]`." +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/reference/diagnostics.po b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/diagnostics.po new file mode 100644 index 000000000..a1e2e33ca --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/diagnostics.po @@ -0,0 +1,229 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/reference/diagnostics.md:1 +msgid "Diagnostics" +msgstr "" + +#: ../../source/reference/diagnostics.md:3 +#, python-brace-format +msgid "" +"Diagnostics can be suppressed through " +"{emmyrc:obj}`EmmyRc.diagnostics.disable`. You can also change severity of" +" an individual diagnostic with {emmyrc:obj}`EmmyRc.diagnostics.severity`." +msgstr "" + +#: ../../source/reference/diagnostics.md:7 +#, python-brace-format +msgid "" +"Some diagnostics are disabled by default. You can re-enable them by " +"adding their codes to {emmyrc:obj}`EmmyRc.diagnostics.enables`." +msgstr "" + +#: ../../source/reference/diagnostics.md:10 +msgid "Full list of diagnostic codes" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Syntax error" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Doc syntax error" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Type not found" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Missing return statement" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Param Type not match" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Missing parameter" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Redundant parameter" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Unreachable code" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Unused" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Undefined global" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Deprecated" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Access invisible" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Discard return value" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Undefined field" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Local const reassign" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Iter variable reassign" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Duplicate type" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Redefined local" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Redefined label" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Code style check" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Need check nil" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Await in sync" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Doc tag usage error" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Return type mismatch" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Missing return value" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Redundant return value" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Undefined Doc Param" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Duplicate doc field" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Unknown doc annotation" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Missing fields" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Inject Field" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Circle Doc Class" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Incomplete signature doc" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Missing global doc" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Assign type mismatch" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Duplicate require" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "non-literal-expressions-in-assert" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "Unbalanced assignments" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "unnecessary-assert" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "unnecessary-if" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "duplicate-set-field" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "duplicate-index" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "generic-constraint-mismatch" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "cast-type-mismatch" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "require-module-not-visible" +msgstr "" + +#: ../../source/reference/diagnostics.md:14 +msgid "enum-value-mismatch" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/reference/index.po b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/index.po new file mode 100644 index 000000000..57aa26aed --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/index.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/reference/index.md:1 +msgid "Reference" +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/reference/types.po b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/types.po new file mode 100644 index 000000000..e5c4a76de --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/reference/types.po @@ -0,0 +1,267 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-21 00:14+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/reference/types.md:1 +msgid "Types" +msgstr "" + +#: ../../source/reference/types.md:3 +msgid "Built-in types" +msgstr "" + +#: ../../source/reference/types.md:6 +#, python-brace-format +msgid "" +"The type {lua}`nil` has one single value, *nil*, whose main property is " +"to be different from any other value; it usually represents the absence " +"of a useful value." +msgstr "" + +#: ../../source/reference/types.md:9 +#, python-brace-format +msgid "" +"The type {lua}`boolean` has two values, *false* and *true*. Both " +"{lua}`nil` and *false* make a condition false; any other value makes it " +"true." +msgstr "" + +#: ../../source/reference/types.md:12 +msgid "" +"Lua uses two internal representations for numbers: *integer* and *float*." +" It has explicit rules about when each representation is used, but it " +"also converts between them automatically as needed." +msgstr "" + +#: ../../source/reference/types.md:16 +#, python-brace-format +msgid "" +"EmmyLua, on the other hand, allows explicitly annotating which " +"representation is expected. The {lua}`number` type can contain both " +"*integer* and *float* values. The {lua}`integer` is a sub-type of " +"{lua}`number`, and only allows *integer* values." +msgstr "" + +#: ../../source/reference/types.md:21 ../../source/reference/types.md:24 +#: ../../source/reference/types.md:53 +msgid "See also" +msgstr "" + +#: ../../source/reference/types.md:22 ../../source/reference/types.md:25 +#: ../../source/reference/types.md:54 +msgid "Lua's [manual on value types]." +msgstr "" + +#: ../../source/reference/types.md:15 +#, python-brace-format +msgid "" +"The type {lua}`integer` is a sub-type of {lua}`number` that only allows " +"numbers with *integer* representation." +msgstr "" + +#: ../../source/reference/types.md:18 +#, python-brace-format +msgid "" +"The type {lua}`userdata` is provided to allow arbitrary C data to be " +"stored in Lua variables. A userdata value represents a block of raw " +"memory. There are two kinds of userdata: {lua}`userdata`, which is an " +"object with a block of memory managed by Lua, and {lua}`lightuserdata`, " +"which is simply a C pointer value." +msgstr "" + +#: ../../source/reference/types.md:21 +#, python-brace-format +msgid "" +"The type {lua}`lightuserdata` is a sub-type of {lua}`userdata` that only " +"allows values with *light userdata* representation." +msgstr "" + +#: ../../source/reference/types.md:24 +#, python-brace-format +msgid "" +"The type {lua}`thread` represents independent threads of execution and it" +" is used to implement coroutines. Lua threads are not related to " +"operating-system threads. Lua supports coroutines on all systems, even " +"those that do not support threads natively." +msgstr "" + +#: ../../source/reference/types.md:27 +#, python-brace-format +msgid "" +"The type *table* implements associative arrays, that is, arrays that can " +"have as indices not only numbers, but any Lua value except {lua}`nil` and" +" {lua}`NaN `. (*Not a Number* is a special floating-point value " +"used by the IEEE 754 standard to represent undefined or unrepresentable " +"numerical results, such as `0/0`.)" +msgstr "" + +#: ../../source/reference/types.md:33 +msgid "" +"While lua allows mixing types of keys and values in a table, EmmyLua has " +"an option to specify their exact types. Simply using type `table` creates" +" a heterogeneous table (equivalent to `table`), while " +"explicitly providing key and value types creates a homogeneous table:" +msgstr "" + +#: ../../source/reference/types.md:46 +msgid "" +"You can also specify the exact shape of a table by using a *table " +"literal*:" +msgstr "" + +#: ../../source/reference/types.md:30 +#, python-brace-format +msgid "" +"The type {lua}`any` is compatible with any other type. That is, all types" +" can be converted to and from {lua}`any`." +msgstr "" + +#: ../../source/reference/types.md:33 +msgid "" +"This type is a way to bypass type checking system and explicitly tell " +"EmmyLua that you know what you're doing." +msgstr "" + +#: ../../source/reference/types.md:36 +msgid "Tip" +msgstr "" + +#: ../../source/reference/types.md:37 +#, python-brace-format +msgid "" +"Prefer using {lua}`unknown` instead of {lua}`any` to signal the need to " +"be careful and explicitly check value's contents." +msgstr "" + +#: ../../source/reference/types.md:33 +#, python-brace-format +msgid "" +"The type {lua}`unknown` is similar to {lua}`any`, but signifies a " +"different intent." +msgstr "" + +#: ../../source/reference/types.md:36 +#, python-brace-format +msgid "" +"While {lua}`any` is a way to say \"I know what I'm doing\", " +"{lua}`unknown` is a way to say \"better check this value before using " +"it\"." +msgstr "" + +#: ../../source/reference/types.md:36 +#, python-brace-format +msgid "" +"Void is an alias for {lua}`nil` used in some code bases. Prefer using " +"{lua}`nil` instead." +msgstr "" + +#: ../../source/reference/types.md:39 +#, python-brace-format +msgid "" +"A special type used with class methods. It can be thought of as a generic" +" parameter that matches type of the function's implicit argument `self`. " +"That is, when a function is called via colon notation (i.e. " +"`table:method()`), {lua}`self` is replaced with the type of expression " +"before the colon." +msgstr "" + +#: ../../source/reference/types.md:45 +msgid "" +"This is especially handy when dealing with inheritance. Consider the " +"following example:" +msgstr "" + +#: ../../source/reference/types.md:63 +#, python-brace-format +msgid "" +"Here, EmmyLua infers type of `child` to be `Child`, even though `new` was" +" defined in its base class. This is because `new` uses {lua}`self` as its" +" return type." +msgstr "" + +#: ../../source/reference/types.md:41 +msgid "Metaprogramming library" +msgstr "" + +#: ../../source/reference/types.md:44 +#, python-brace-format +msgid "" +"A type for {lua}`assert` function. Given a nullable type `T` expands to a" +" non-nullable version of `T`." +msgstr "" + +#: ../../source/reference/types.md:47 +msgid "For example, if `T` is `string?`, then `std.NotNull` will be `string`." +msgstr "" + +#: ../../source/reference/types.md:57 +#, python-brace-format +msgid "" +"A type for {lua}`table.unpack` function. Given a type `T` and optional " +"literal types `Start` and `End`, expands to the type of expression " +"`table.unpack(t, start, end)`." +msgstr "" + +#: ../../source/reference/types.md:61 ../../source/reference/types.md:64 +msgid "Example:" +msgstr "" + +#: ../../source/reference/types.md:72 +msgid "Here, `a`, `b` and `c` will be inferred as integers." +msgstr "" + +#: ../../source/reference/types.md:60 +#, python-brace-format +msgid "" +"A type for {lua}`rawget` function. Given a type `T` and a literal type " +"`K`, expands to the type of expression `rawget(t, k)`." +msgstr "" + +#: ../../source/reference/types.md:74 +msgid "Here, `std.RawGet` will be expanded to `integer`." +msgstr "" + +#: ../../source/reference/types.md:63 +msgid "A wrapper for matching literal types in generics." +msgstr "" + +#: ../../source/reference/types.md:65 +msgid "" +"By default, generics variables that match literal values decay to values'" +" base types:" +msgstr "" + +#: ../../source/reference/types.md:81 +msgid "" +"Here, type of `value` will be inferred as `string` even though " +"`original`'s type was `\"literal\"`." +msgstr "" + +#: ../../source/reference/types.md:84 +msgid "" +"We can prevent this behavior by wrapping generic pattern for `T` into " +"`std.ConstTpl`:" +msgstr "" + +#: ../../source/reference/types.md:100 +msgid "Here, type of `value` will be inferred as `\"literal\"`." +msgstr "" + diff --git a/docs/v2/source/_locales/zh/LC_MESSAGES/types.po b/docs/v2/source/_locales/zh/LC_MESSAGES/types.po new file mode 100644 index 000000000..21fc19e4f --- /dev/null +++ b/docs/v2/source/_locales/zh/LC_MESSAGES/types.po @@ -0,0 +1,265 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2025, CppCXY +# This file is distributed under the same license as the EmmyLua Analyzer +# package. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: EmmyLua Analyzer \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-20 22:44+0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh\n" +"Language-Team: zh \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: ../../source/types.md:1 +msgid "Types" +msgstr "" + +#: ../../source/types.md:3 +msgid "Built-in types" +msgstr "" + +#: ../../source/types.md:6 +#, python-brace-format +msgid "" +"The type {lua}`nil` has one single value, *nil*, whose main property is " +"to be different from any other value; it usually represents the absence " +"of a useful value." +msgstr "" + +#: ../../source/types.md:9 +#, python-brace-format +msgid "" +"The type {lua}`boolean` has two values, *false* and *true*. Both " +"{lua}`nil` and *false* make a condition false; any other value makes it " +"true." +msgstr "" + +#: ../../source/types.md:12 +msgid "" +"Lua uses two internal representations for numbers: *integer* and *float*." +" It has explicit rules about when each representation is used, but it " +"also converts between them automatically as needed." +msgstr "" + +#: ../../source/types.md:16 +#, python-brace-format +msgid "" +"EmmyLua, on the other hand, allows explicitly annotating which " +"representation is expected. The {lua}`number` type can contain both " +"*integer* and *float* values. The {lua}`integer` is a sub-type of " +"{lua}`number`, and only allows *integer* values." +msgstr "" + +#: ../../source/types.md:21 ../../source/types.md:24 ../../source/types.md:53 +msgid "See also" +msgstr "" + +#: ../../source/types.md:22 ../../source/types.md:25 ../../source/types.md:54 +msgid "Lua's [manual on value types]." +msgstr "" + +#: ../../source/types.md:15 +#, python-brace-format +msgid "" +"The type {lua}`integer` is a sub-type of {lua}`number` that only allows " +"numbers with *integer* representation." +msgstr "" + +#: ../../source/types.md:18 +#, python-brace-format +msgid "" +"The type {lua}`userdata` is provided to allow arbitrary C data to be " +"stored in Lua variables. A userdata value represents a block of raw " +"memory. There are two kinds of userdata: {lua}`userdata`, which is an " +"object with a block of memory managed by Lua, and {lua}`lightuserdata`, " +"which is simply a C pointer value." +msgstr "" + +#: ../../source/types.md:21 +#, python-brace-format +msgid "" +"The type {lua}`lightuserdata` is a sub-type of {lua}`userdata` that only " +"allows values with *light userdata* representation." +msgstr "" + +#: ../../source/types.md:24 +#, python-brace-format +msgid "" +"The type {lua}`thread` represents independent threads of execution and it" +" is used to implement coroutines. Lua threads are not related to " +"operating-system threads. Lua supports coroutines on all systems, even " +"those that do not support threads natively." +msgstr "" + +#: ../../source/types.md:27 +#, python-brace-format +msgid "" +"The type *table* implements associative arrays, that is, arrays that can " +"have as indices not only numbers, but any Lua value except {lua}`nil` and" +" {lua}`NaN `. (*Not a Number* is a special floating-point value " +"used by the IEEE 754 standard to represent undefined or unrepresentable " +"numerical results, such as `0/0`.)" +msgstr "" + +#: ../../source/types.md:33 +msgid "" +"While lua allows mixing types of keys and values in a table, EmmyLua has " +"an option to specify their exact types. Simply using type `table` creates" +" a heterogeneous table (equivalent to `table`), while " +"explicitly providing key and value types creates a homogeneous table:" +msgstr "" + +#: ../../source/types.md:46 +msgid "" +"You can also specify the exact shape of a table by using a *table " +"literal*:" +msgstr "" + +#: ../../source/types.md:30 +#, python-brace-format +msgid "" +"The type {lua}`any` is compatible with any other type. That is, all types" +" can be converted to and from {lua}`any`." +msgstr "" + +#: ../../source/types.md:33 +msgid "" +"This type is a way to bypass type checking system and explicitly tell " +"EmmyLua that you know what you're doing." +msgstr "" + +#: ../../source/types.md:36 +msgid "Tip" +msgstr "" + +#: ../../source/types.md:37 +#, python-brace-format +msgid "" +"Prefer using {lua}`unknown` instead of {lua}`any` to signal the need to " +"be careful and explicitly check value's contents." +msgstr "" + +#: ../../source/types.md:33 +#, python-brace-format +msgid "" +"The type {lua}`unknown` is similar to {lua}`any`, but signifies a " +"different intent." +msgstr "" + +#: ../../source/types.md:36 +#, python-brace-format +msgid "" +"While {lua}`any` is a way to say \"I know what I'm doing\", " +"{lua}`unknown` is a way to say \"better check this value before using " +"it\"." +msgstr "" + +#: ../../source/types.md:36 +#, python-brace-format +msgid "" +"Void is an alias for {lua}`nil` used in some code bases. Prefer using " +"{lua}`nil` instead." +msgstr "" + +#: ../../source/types.md:39 +#, python-brace-format +msgid "" +"A special type used with class methods. It can be thought of as a generic" +" parameter that matches type of the function's implicit argument `self`. " +"That is, when a function is called via colon notation (i.e. " +"`table:method()`), {lua}`self` is replaced with the type of expression " +"before the colon." +msgstr "" + +#: ../../source/types.md:45 +msgid "" +"This is especially handy when dealing with inheritance. Consider the " +"following example:" +msgstr "" + +#: ../../source/types.md:63 +#, python-brace-format +msgid "" +"Here, EmmyLua infers type of `child` to be `Child`, even though `new` was" +" defined in its base class. This is because `new` uses {lua}`self` as its" +" return type." +msgstr "" + +#: ../../source/types.md:41 +msgid "Metaprogramming library" +msgstr "" + +#: ../../source/types.md:44 +#, python-brace-format +msgid "" +"A type for {lua}`assert` function. Given a nullable type `T` expands to a" +" non-nullable version of `T`." +msgstr "" + +#: ../../source/types.md:47 +msgid "For example, if `T` is `string?`, then `std.NotNull` will be `string`." +msgstr "" + +#: ../../source/types.md:57 +#, python-brace-format +msgid "" +"A type for {lua}`table.unpack` function. Given a type `T` and optional " +"literal types `Start` and `End`, expands to the type of expression " +"`table.unpack(t, start, end)`." +msgstr "" + +#: ../../source/types.md:61 ../../source/types.md:64 +msgid "Example:" +msgstr "" + +#: ../../source/types.md:72 +msgid "Here, `a`, `b` and `c` will be inferred as integers." +msgstr "" + +#: ../../source/types.md:60 +#, python-brace-format +msgid "" +"A type for {lua}`rawget` function. Given a type `T` and a literal type " +"`K`, expands to the type of expression `rawget(t, k)`." +msgstr "" + +#: ../../source/types.md:74 +msgid "Here, `std.RawGet` will be expanded to `integer`." +msgstr "" + +#: ../../source/types.md:63 +msgid "A wrapper for matching literal types in generics." +msgstr "" + +#: ../../source/types.md:65 +msgid "" +"By default, generics variables that match literal values decay to values'" +" base types:" +msgstr "" + +#: ../../source/types.md:81 +msgid "" +"Here, type of `value` will be inferred as `string` even though " +"`original`'s type was `\"literal\"`." +msgstr "" + +#: ../../source/types.md:84 +msgid "" +"We can prevent this behavior by wrapping generic pattern for `T` into " +"`std.ConstTpl`:" +msgstr "" + +#: ../../source/types.md:100 +msgid "Here, type of `value` will be inferred as `\"literal\"`." +msgstr "" + diff --git a/docs/v2/source/_root/.nojekyll b/docs/v2/source/_root/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/docs/v2/source/_root/index.html b/docs/v2/source/_root/index.html new file mode 100644 index 000000000..76c19375f --- /dev/null +++ b/docs/v2/source/_root/index.html @@ -0,0 +1,30 @@ + + + + Redirecting... + + + + + + +

Redirecting to the main page.

+

If redirect didn't happen, choose the language manually:

+ + + diff --git a/docs/v2/source/_static/extra.css b/docs/v2/source/_static/extra.css new file mode 100644 index 000000000..06deda86f --- /dev/null +++ b/docs/v2/source/_static/extra.css @@ -0,0 +1,3 @@ +.admonition.spoiler .admonition-title { + background: none; +} diff --git a/docs/v2/source/_templates/.icons/emmy.svg b/docs/v2/source/_templates/.icons/emmy.svg new file mode 100644 index 000000000..35df4362b --- /dev/null +++ b/docs/v2/source/_templates/.icons/emmy.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/v2/source/_templates/.icons/fav.svg b/docs/v2/source/_templates/.icons/fav.svg new file mode 100644 index 000000000..c1d25f17d --- /dev/null +++ b/docs/v2/source/_templates/.icons/fav.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/v2/source/_templates/base.html b/docs/v2/source/_templates/base.html new file mode 100644 index 000000000..c10f9ff3d --- /dev/null +++ b/docs/v2/source/_templates/base.html @@ -0,0 +1,5 @@ +{% extends "!base.html" %} + +{% block announce %} +

Warning: this is a work-in-progress version of EmmyLua documentation.

+{% endblock %} diff --git a/docs/v2/source/_templates/partials/alternate.html b/docs/v2/source/_templates/partials/alternate.html new file mode 100644 index 000000000..4494e791f --- /dev/null +++ b/docs/v2/source/_templates/partials/alternate.html @@ -0,0 +1,50 @@ + + + +
+
+ {% set icon = config.theme.icon.alternate or "material/translate" %} + +
+ +
+
+
diff --git a/docs/v2/source/conf.py b/docs/v2/source/conf.py new file mode 100644 index 000000000..4ded134cf --- /dev/null +++ b/docs/v2/source/conf.py @@ -0,0 +1,142 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +import sys +import get_version as _get_version +import pathlib as _pathlib +import datetime as _datetime + +_src_root = _pathlib.Path(__file__).parent +_vcs_root = _get_version.find_vcs_root(_src_root) +assert _vcs_root, "failed to find git root" + +sys.path.insert(0, str(_src_root / "_extensions")) + +project = "EmmyLua Analyzer" +copyright = f"{_datetime.date.today().year}, CppCXY" +author = "CppCXY and contributors" +release = _get_version.get_version_from_vcs(_vcs_root) + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_immaterial", + "sphinx_lua_ls", + "emmyrc", +] + +primary_domain = "lua" + +lua_ls_project_root = "../../../crates/emmylua_code_analysis/resources/std" +lua_ls_backend = "emmylua" + +emmylua_schema = "../../../crates/emmylua_code_analysis/resources/schema.json" + +myst_enable_extensions = {"colon_fence"} +myst_heading_anchors = 3 + +gettext_compact = False + +locale_dirs = ["_locales"] +html_theme = "sphinx_immaterial" +html_static_path = ["_static"] +templates_path = ["_templates"] +html_css_files = ["extra.css"] +html_favicon = "_templates/.icons/fav.svg" +html_theme_options = { + "icon": { + "logo": "emmy", + "repo": "fontawesome/brands/github", + }, + "site_url": "https://EmmyLuaLs.github.io/emmylua-analyzer-rust/", + "repo_url": "https://github.com/EmmyLuaLs/emmylua-analyzer-rust/", + "edit_uri": "blob/main/docs/v2", + "globaltoc_collapse": True, + "features": [ + "content.action.edit", + "content.action.view", + "content.code.annotate", + "content.code.copy", + "content.tabs.link", + # "content.tooltips", + "navigation.instant", + "navigation.sections", + "navigation.tabs", + "navigation.top", + "search.highlight", + "search.suggest", + "toc.follow", + "toc.sticky", + "announce.dismiss", + ], + "palette": [ + { + "media": "(prefers-color-scheme)", + "toggle": { + "icon": "material/brightness-auto", + "name": "Switch to light mode", + }, + }, + { + "media": "(prefers-color-scheme: light)", + "scheme": "default", + "primary": "blue", + "accent": "blue", + "toggle": { + "icon": "material/lightbulb", + "name": "Switch to dark mode", + }, + }, + { + "media": "(prefers-color-scheme: dark)", + "scheme": "slate", + "primary": "black", + "accent": "blue", + "toggle": { + "icon": "material/lightbulb-outline", + "name": "Switch to system preference", + }, + }, + ], + "toc_title_is_page_title": True, + "languages": [ + { + "name": "English", + "link": "../en/", + "lang": "en", + }, + { + "name": "中文", + "link": "../zh/", + "lang": "zh", + }, + ], + "scope": "/", + # # BEGIN: social icons + # "social": [ + # { + # "icon": "fontawesome/brands/github", + # "link": "https://github.com/jbms/sphinx-immaterial", + # "name": "Source on github.com", + # }, + # { + # "icon": "fontawesome/brands/python", + # "link": "https://pypi.org/project/sphinx-immaterial/", + # }, + # ], + # # END: social icons +} +sphinx_immaterial_custom_admonitions = [ + { + "name": "spoiler", + "icon": "material/arrow-expand", + "classes": ["spoiler", "quote"], + } +] diff --git a/docs/v2/source/guide/configuration.md b/docs/v2/source/guide/configuration.md new file mode 100644 index 000000000..d4d4a5610 --- /dev/null +++ b/docs/v2/source/guide/configuration.md @@ -0,0 +1,83 @@ +# Configuration + +EmmyLua loads settings from `.emmyrc.json` located in project's root. +For settings that aren't listed in project's `.emmyrc.json`, EmmyLua will search +for user-specific defaults. + +:::{seealso} + Full list of configuration values + [is available in the reference section](../reference/configuration.md#full-list-of-config-values). +::: + +## Compatibility with LuaLs + +If your project uses LuaLs, EmmyLua will be able to extract some settings +from `.luarc.json`. However, `.emmyrc.json` configuration format is more +feature-rich, and incompatible parts will be automatically ignored. + +## Project settings + +Create an `.emmyrc.json` in the root directory of your project. At the minimum, +you'll want to configure Lua runtime version: + +```json +{ + "runtime": { + "version": "Lua5.4" + } +} +``` + +To kick-start configuration process you can use this template. It contains +all project-specific settings along with their default values: + +:::{spoiler} A template for project-specific `.emmyrc.json` + :collapsible: + + ```{emmyrc:auto-example} EmmyRc + :kind: project + ``` +::: + +:::{tip} + Only add project-specific setting to your project's `.emmyrc.json`. For example, + it's a good idea to set up [Lua version](#EmmyRc.runtime.version) + or [naming convention for auto-required paths](#EmmyRc.completion.autoRequireNamingConvention), + but overriding [settings for inlay hints](#EmmyRc.hint) would serve + no purpose. +::: + +## User settings + +You can override default settings by creating an `.emmyrc.json` in your home +or config directory. + +:::{seealso} + Full list of places where EmmyLua searches for configs + [is available in the reference section](../reference/configuration.md#loading-order). +::: + +Additionally, some editors allow overriding project's config values. +See [installation instructions](installation) for details. + +To kick-start configuration process you can use this template. It contains +all user-specific settings along with their default values: + +:::{spoiler} A template for user-specific `.emmyrc.json` + :collapsible: + + ```{emmyrc:auto-example} EmmyRc + :kind: user + ``` +::: + +## Schema + +To enable intelligent completion and validation for configuration files, +you can add a schema reference to your configuration file: + +```json +{ + "$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json" +} +``` diff --git a/docs/v2/source/guide/features.md b/docs/v2/source/guide/features.md new file mode 100644 index 000000000..ead022319 --- /dev/null +++ b/docs/v2/source/guide/features.md @@ -0,0 +1 @@ +# Features diff --git a/docs/v2/source/guide/index.md b/docs/v2/source/guide/index.md new file mode 100644 index 000000000..cccfc48d7 --- /dev/null +++ b/docs/v2/source/guide/index.md @@ -0,0 +1,46 @@ +# Guide + +```{toctree} +:maxdepth: 2 + +installation +configuration +features +``` + + diff --git a/docs/v2/source/guide/installation.md b/docs/v2/source/guide/installation.md new file mode 100644 index 000000000..172c803f5 --- /dev/null +++ b/docs/v2/source/guide/installation.md @@ -0,0 +1,89 @@ +# Installation + +## VSCode + +Install the [EmmyLua Extension] for the best development experience. + +[EmmyLua Extension]: https://marketplace.visualstudio.com/items?itemName=tangzx.emmylua + +## Intellij Idea + +Install the [EmmyLua2 Plugin] from the JetBrains Marketplace. + +[EmmyLua2 Plugin]: https://plugins.jetbrains.com/plugin/25076-emmylua2 + +## NeoVim + +1. Install EmmyLua to your system using `cargo` + (or another method, [see below](#standalone)): + + ```sh + cargo install emmylua_ls + ``` + +2. Install [nvim-lspconfig]. + + [nvim-lspconfig]: https://github.com/neovim/nvim-lspconfig?tab=readme-ov-file#install + +3. Enable LSP client in your `init.lua`: + + ```lua + vim.lsp.enable({"emmylua_ls"}) + ``` + +4. You can [configure](./configuration.md) EmmyLua via `vim.lsp.config`: + + ```lua + vim.lsp.config('emmylua_ls', { + settings = { + emmylua = { + -- Anything from `.emmyrc.json`, for example: + hint = { + paramHint = false + } + } + } + }) + ``` + + See [`:help lspconfig-all | /emmylua_ls`][nvim-help] for more info. + + [nvim-help]: https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#emmylua_ls + + :::{note} + These options will override project-specific `.emmyrc.json`. + + For options that control LSP features, this is a desired behavior; + for options that control language analysis, it is not. + + If you need to alter defaults without overriding project-specific settings, + you can do so by creating `.emmyrc.json` in your home + or config directory. See [](configuration.md#user-settings) for details. + ::: + +## Standalone + +EmmyLua is available as a standalone executable. + +**Via Cargo:** + +1. [Install Rust and Cargo]. + +2. ```sh + # Install the language server + cargo install emmylua_ls + + # Install documentation generator + cargo install emmylua_doc_cli + + # Install static analyzer + cargo install emmylua_check + ``` + +[Install Rust and Cargo]: https://doc.rust-lang.org/cargo/getting-started/installation.html + +**Pre-built binaries:** + +Download the latest binaries from our [releases page]. + +[releases page]: https://github.com/CppCXY/emmylua-analyzer-rust/releases diff --git a/docs/v2/source/index.md b/docs/v2/source/index.md new file mode 100644 index 000000000..e5a88f4d0 --- /dev/null +++ b/docs/v2/source/index.md @@ -0,0 +1,8 @@ +# EmmyLua Analyzer + +```{toctree} +:maxdepth: 2 + +guide/index +reference/index +``` diff --git a/docs/v2/source/reference/annotations.md b/docs/v2/source/reference/annotations.md new file mode 100644 index 000000000..64b873fa5 --- /dev/null +++ b/docs/v2/source/reference/annotations.md @@ -0,0 +1,54 @@ +# Annotations + + diff --git a/docs/v2/source/reference/configuration.md b/docs/v2/source/reference/configuration.md new file mode 100644 index 000000000..3eef46591 --- /dev/null +++ b/docs/v2/source/reference/configuration.md @@ -0,0 +1,35 @@ +# Configuration + +:::{seealso} + See our guide on [how to configure EmmyLua](../guide/configuration.md). +::: + +## Loading order + +EmmyLua will search for configs in the following order. Values from configs +higher in the list override values from configs lower in the list: + +1. local `.emmyrc.json`: a JSON file located in your project's root, +2. local `.luarc.json`: a JSON file located in your project's root, +3. a JSON file specified by environment variable `$EMMYLUALS_CONFIG`, +4. global `/emmylua_ls/.emmyrc.json`, +5. global `/emmylua_ls/.luarc.json`, +6. global `/.emmyrc.json`, +7. global `/.luarc.json`. + +Depending on your platform, `` will be different: + +| Platform | Value | Example | +|----------|---------------------------------------|--------------------------------------------| +| Linux | `$XDG_CONFIG_HOME` or `$HOME/.config` | `/home/alice/.config` | +| macOS | `$HOME/Library/Application Support` | `/Users/Alice/Library/Application Support` | +| Windows | `{FOLDERID_RoamingAppData}` | `C:\Users\Alice\AppData\Roaming` | + +## Full list of config values + +```{emmyrc:auto} EmmyRc +:recursive: +:unwrap: +:hide-prefix: +:exclude: EmmyRc $schema, EmmyRc#/$defs/DiagnosticCode +``` diff --git a/docs/v2/source/reference/diagnostics.md b/docs/v2/source/reference/diagnostics.md new file mode 100644 index 000000000..99728bf81 --- /dev/null +++ b/docs/v2/source/reference/diagnostics.md @@ -0,0 +1,14 @@ +# Diagnostics + +Diagnostics can be suppressed through {emmyrc:obj}`EmmyRc.diagnostics.disable`. +You can also change severity of an individual diagnostic +with {emmyrc:obj}`EmmyRc.diagnostics.severity`. + +Some diagnostics are disabled by default. You can re-enable them by adding their codes +to {emmyrc:obj}`EmmyRc.diagnostics.enables`. + +## Full list of diagnostic codes + +```{emmyrc:auto} EmmyRc#/$defs/DiagnosticCode +:recursive: +``` diff --git a/docs/v2/source/reference/index.md b/docs/v2/source/reference/index.md new file mode 100644 index 000000000..cce912448 --- /dev/null +++ b/docs/v2/source/reference/index.md @@ -0,0 +1,10 @@ +# Reference + +```{toctree} +:maxdepth: 2 + +annotations +configuration +diagnostics +types +``` diff --git a/docs/v2/source/reference/types.md b/docs/v2/source/reference/types.md new file mode 100644 index 000000000..9fdb56896 --- /dev/null +++ b/docs/v2/source/reference/types.md @@ -0,0 +1,63 @@ +# Types + +## Built-in types + +```{lua:autoobject} nil +``` + +```{lua:autoobject} boolean +``` + +```{lua:autoobject} number +``` + +```{lua:autoobject} integer +``` + +```{lua:autoobject} userdata +``` + +```{lua:autoobject} lightuserdata +``` + +```{lua:autoobject} thread +``` + +```{lua:autoobject} table +``` + +```{lua:autoobject} any +``` + +```{lua:autoobject} unknown +``` + +```{lua:autoobject} void +``` + +```{lua:autoobject} self +``` + +## Metaprogramming library + +```{lua:autoobject} std.NotNull +``` + + + + + +```{lua:autoobject} std.Unpack +``` + +```{lua:autoobject} std.RawGet +``` + +```{lua:autoobject} std.ConstTpl +```