From c7068da3868a5cefdfa911b214fecb1cea28d6d7 Mon Sep 17 00:00:00 2001 From: Grab Date: Wed, 21 Sep 2022 23:37:31 +0200 Subject: [PATCH] Fix syntax, scope, activation, feat builtins Fix all core syntax from non available lua api. Removing sumneko partially/unsuported libs (builtins). Add a command to switch from/to user/core builtins. Settings for a core project now only affects the current project (workspace) no more affect your (user settings) other lua projects. vscode-core extension now only started from core project not for all lua files (detect meta.pbt file) --- package-lock.json | 4 +- package.json | 12 +- src/EmmyLua/core-builtin-basic-api.def.lua | 409 +++++++++++++++++++ src/EmmyLua/core-builtin-os-api.def.lua | 186 +++++++++ src/EmmyLua/core-builtin-package-api.def.lua | 108 +++++ src/EmmyLua/core-builtin-string-api.def.lua | 220 ++++++++++ src/extension.ts | 143 ++++++- 7 files changed, 1069 insertions(+), 13 deletions(-) create mode 100644 src/EmmyLua/core-builtin-basic-api.def.lua create mode 100644 src/EmmyLua/core-builtin-os-api.def.lua create mode 100644 src/EmmyLua/core-builtin-package-api.def.lua create mode 100644 src/EmmyLua/core-builtin-string-api.def.lua diff --git a/package-lock.json b/package-lock.json index a267eed5..9282dc57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-core", - "version": "1.9.3", + "version": "1.9.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-core", - "version": "1.9.3", + "version": "1.9.4", "license": "MIT", "devDependencies": { "@types/chai": "^4.3.3", diff --git a/package.json b/package.json index fbd651fe..15cb8791 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Core Lua API", "description": "Adds support for the Core Games Lua API", "license": "MIT", - "version": "1.9.3", + "version": "1.9.4", "icon": "images/logo.png", "publisher": "ManticoreGames", "repository": { @@ -34,12 +34,20 @@ "ui" ], "activationEvents": [ - "onLanguage:lua" + "workspaceContains:**/Meta.pbt" ], "extensionDependencies": [ "sumneko.lua" ], "main": "./out/extension.js", + "contributes": { + "commands": [ + { + "command": "extension.SetLuaBuiltins", + "title": "Core Enable/Disable Lua builtins" + } + ] + }, "scripts": { "vscode:prepublish": "npm run -S esbuild-base -- --minify && cp -r ./src/EmmyLua ./out/EmmyLua", "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node", diff --git a/src/EmmyLua/core-builtin-basic-api.def.lua b/src/EmmyLua/core-builtin-basic-api.def.lua new file mode 100644 index 00000000..fa0fdadd --- /dev/null +++ b/src/EmmyLua/core-builtin-basic-api.def.lua @@ -0,0 +1,409 @@ +---@meta + +--- +---Command-line arguments of Lua Standalone. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-arg"]) +--- +---@type string[] +arg = {} + +--- +---Raises an error if the value of its argument v is false (i.e., `nil` or `false`); otherwise, returns all its arguments. In case of error, `message` is the error object; when absent, it defaults to `"assertion failed!"` +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-assert"]) +--- +---@generic T +---@param v? T +---@param message? any +---@return T +---@return any ... +function assert(v, message, ...) end + +---@alias gcoptions +-- ---|>'"collect"' # Performs a full garbage-collection cycle. +-- ---| '"stop"' # Stops automatic execution. +-- ---| '"restart"' # Restarts automatic execution. +---|> '"count"' # Returns the total memory in Kbytes. +-- ---| '"step"' # Performs a garbage-collection step. +-- ---| '"isrunning"' # Returns whether the collector is running. +-- ---| '"incremental"' # Change the collector mode to incremental. +-- ---| '"generational"' # Change the collector mode to generational. + +--- +---This function is a generic interface to the garbage collector. It performs different functions according to its first argument, `opt`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-collectgarbage"]) +--- +---@param opt? gcoptions +---@return any +function collectgarbage(opt, ...) end + +-- --- +-- ---Opens the named file and executes its content as a Lua chunk. When called without arguments, `dofile` executes the content of the standard input (`stdin`). Returns all values returned by the chunk. In case of errors, `dofile` propagates the error to its caller. (That is, `dofile` does not run in protected mode.) +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-dofile"]) +-- --- +-- ---@param filename? string +-- ---@return any ... +-- function dofile(filename) end + +--- +---Terminates the last protected function called and returns message as the error object. +--- +---Usually, `error` adds some information about the error position at the beginning of the message, if the message is a string. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-error"]) +--- +---@param message any +---@param level? integer +function error(message, level) end + +--- +---A global variable (not a function) that holds the global environment (see [§2.2](command:extension.lua.doc?["en-us/54/manual.html/2.2"])). Lua itself does not use this variable; changing its value does not affect any environment, nor vice versa. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-_G"]) +--- +---@class _G +_G = {} + +-- ---@version 5.1 +-- --- +-- ---Returns the current environment in use by the function. `f` can be a Lua function or a number that specifies the function at that stack level. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-getfenv"]) +-- --- +-- ---@param f? integer|async fun() +-- ---@return table +-- ---@nodiscard +-- function getfenv(f) end + +--- +---If object does not have a metatable, returns nil. Otherwise, if the object's metatable has a __metatable field, returns the associated value. Otherwise, returns the metatable of the given object. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-getmetatable"]) +--- +---@param object any +---@return table metatable +---@nodiscard +function getmetatable(object) end + +--- +---Returns three values (an iterator function, the table `t`, and `0`) so that the construction +---```lua +--- for i,v in ipairs(t) do body end +---``` +---will iterate over the key–value pairs `(1,t[1]), (2,t[2]), ...`, up to the first absent index. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-ipairs"]) +--- +---@generic T: table, V +---@param t T +---@return fun(table: V[], i?: integer):integer, V +---@return T +---@return integer i +function ipairs(t) end + +-- ---@alias loadmode +-- ---| '"b"' # Only binary chunks. +-- ---| '"t"' # Only text chunks. +-- ---|>'"bt"' # Both binary and text. + +-- --- +-- ---Loads a chunk. +-- --- +-- ---If `chunk` is a string, the chunk is this string. If `chunk` is a function, `load` calls it repeatedly to get the chunk pieces. Each call to `chunk` must return a string that concatenates with previous results. A return of an empty string, `nil`, or no value signals the end of the chunk. +-- --- +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-load"]) +-- --- +-- ---@param chunk string|function +-- ---@param chunkname? string +-- ---@param mode? loadmode +-- ---@param env? table +-- ---@return function? +-- ---@return string? error_message +-- ---@nodiscard +-- function load(chunk, chunkname, mode, env) end + +-- --- +-- ---Loads a chunk from file `filename` or from the standard input, if no file name is given. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-loadfile"]) +-- --- +-- ---@param filename? string +-- ---@param mode? loadmode +-- ---@param env? table +-- ---@return function? +-- ---@return string? error_message +-- ---@nodiscard +-- function loadfile(filename, mode, env) end + +-- ---@version 5.1 +-- --- +-- ---Loads a chunk from the given string. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-loadstring"]) +-- --- +-- ---@param text string +-- ---@param chunkname? string +-- ---@return function? +-- ---@return string? error_message +-- ---@nodiscard +-- function loadstring(text, chunkname) end + +-- ---@version 5.1 +-- ---@param proxy boolean|table +-- ---@return userdata +-- ---@nodiscard +-- function newproxy(proxy) end + +-- ---@version 5.1 +-- --- +-- ---Creates a module. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-module"]) +-- --- +-- ---@param name string +-- function module(name, ...) end + +--- +---Allows a program to traverse all fields of a table. Its first argument is a table and its second argument is an index in this table. A call to `next` returns the next index of the table and its associated value. When called with `nil` as its second argument, `next` returns an initial index and its associated value. When called with the last index, or with `nil` in an empty table, `next` returns `nil`. If the second argument is absent, then it is interpreted as `nil`. In particular, you can use `next(t)` to check whether a table is empty. +--- +---The order in which the indices are enumerated is not specified, *even for numeric indices*. (To traverse a table in numerical order, use a numerical `for`.) +--- +---The behavior of `next` is undefined if, during the traversal, you assign any value to a non-existent field in the table. You may however modify existing fields. In particular, you may set existing fields to nil. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-next"]) +--- +---@generic K, V +---@param table table +---@param index? K +---@return K? +---@return V? +---@nodiscard +function next(table, index) end + +--- +---If `t` has a metamethod `__pairs`, calls it with t as argument and returns the first three results from the call. +--- +---Otherwise, returns three values: the [next](command:extension.lua.doc?["en-us/54/manual.html/pdf-next"]) function, the table `t`, and `nil`, so that the construction +---```lua +--- for k,v in pairs(t) do body end +---``` +---will iterate over all key–value pairs of table `t`. +--- +---See function [next](command:extension.lua.doc?["en-us/54/manual.html/pdf-next"]) for the caveats of modifying the table during its traversal. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-pairs"]) +--- +---@generic T: table, K, V +---@param t T +---@return fun(table: table, index?: K):K, V +---@return T +function pairs(t) end + +--- +---Calls the function `f` with the given arguments in *protected mode*. This means that any error inside `f` is not propagated; instead, `pcall` catches the error and returns a status code. Its first result is the status code (a boolean), which is true if the call succeeds without errors. In such case, `pcall` also returns all results from the call, after this first result. In case of any error, `pcall` returns `false` plus the error object. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-pcall"]) +--- +---@param f async fun() +---@param arg1? any +---@return boolean success +---@return any result +---@return any ... +function pcall(f, arg1, ...) end + +--- +---Receives any number of arguments and prints their values to `stdout`, converting each argument to a string following the same rules of [tostring](command:extension.lua.doc?["en-us/54/manual.html/pdf-tostring"]). +---The function print is not intended for formatted output, but only as a quick way to show a value, for instance for debugging. For complete control over the output, use [string.format](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.format"]) and [io.write](command:extension.lua.doc?["en-us/54/manual.html/pdf-io.write"]). +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-print"]) +--- +function print(...) end + +--- +---Checks whether v1 is equal to v2, without invoking the `__eq` metamethod. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-rawequal"]) +--- +---@param v1 any +---@param v2 any +---@return boolean +---@nodiscard +function rawequal(v1, v2) end + +--- +---Gets the real value of `table[index]`, without invoking the `__index` metamethod. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-rawget"]) +--- +---@param table table +---@param index any +---@return any +---@nodiscard +function rawget(table, index) end + +-- Todo: check if not available +-- --- +-- ---Returns the length of the object `v`, without invoking the `__len` metamethod. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-rawlen"]) +-- --- +-- ---@param v table|string +-- ---@return integer len +-- ---@nodiscard +-- function rawlen(v) end + +--- +---Sets the real value of `table[index]` to `value`, without using the `__newindex` metavalue. `table` must be a table, `index` any value different from `nil` and `NaN`, and `value` any Lua value. +---This function returns `table`. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-rawset"]) +--- +---@param table table +---@param index any +---@param value any +---@return table +function rawset(table, index, value) end + +--- +---If `index` is a number, returns all arguments after argument number `index`; a negative number indexes from the end (`-1` is the last argument). Otherwise, `index` must be the string `"#"`, and `select` returns the total number of extra arguments it received. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-select"]) +--- +---@param index integer|'"#"' +---@return any +---@nodiscard +function select(index, ...) end + +-- ---@version 5.1 +-- --- +-- ---Sets the environment to be used by the given function. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-setfenv"]) +-- --- +-- ---@param f async fun()|integer +-- ---@param table table +-- ---@return function +-- function setfenv(f, table) end + +--- +---Sets the metatable for the given table. If `metatable` is `nil`, removes the metatable of the given table. If the original metatable has a `__metatable` field, raises an error. +--- +---This function returns `table`. +--- +---To change the metatable of other types from Lua code, you must use the debug library ([§6.10](command:extension.lua.doc?["en-us/54/manual.html/6.10"])). +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-setmetatable"]) +--- +---@param table table +---@param metatable? table +---@return table +function setmetatable(table, metatable) end + +--- +---When called with no `base`, `tonumber` tries to convert its argument to a number. If the argument is already a number or a string convertible to a number, then `tonumber` returns this number; otherwise, it returns `fail`. +--- +---The conversion of strings can result in integers or floats, according to the lexical conventions of Lua (see [§3.1](command:extension.lua.doc?["en-us/54/manual.html/3.1"])). The string may have leading and trailing spaces and a sign. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-tonumber"]) +--- +---@overload fun(e: string, base: integer):integer +---@param e any +---@return number? +---@nodiscard +function tonumber(e) end + +--- +---Receives a value of any type and converts it to a string in a human-readable format. +--- +---If the metatable of `v` has a `__tostring` field, then `tostring` calls the corresponding value with `v` as argument, and uses the result of the call as its result. Otherwise, if the metatable of `v` has a `__name` field with a string value, `tostring` may use that string in its final result. +--- +---For complete control of how numbers are converted, use [string.format](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.format"]). +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-tostring"]) +--- +---@param v any +---@return string +---@nodiscard +function tostring(v) end + +---@alias type +---| '"nil"' +---| '"number"' +---| '"string"' +---| '"boolean"' +---| '"table"' +---| '"function"' +---| '"thread"' +---| '"userdata"' + +--- +---Returns the type of its only argument, coded as a string. The possible results of this function are `"nil"` (a string, not the value `nil`), `"number"`, `"string"`, `"boolean"`, `"table"`, `"function"`, `"thread"`, and `"userdata"`. +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-type"]) +--- +---@param v any +---@return type type +---@nodiscard +function type(v) end + +--- +---A global variable (not a function) that holds a string containing the running Lua version. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-_VERSION"]) +--- +_VERSION = 'Lua 5.4' + +---@version >5.4 +--- +---Emits a warning with a message composed by the concatenation of all its arguments (which should be strings). +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-warn"]) +--- +---@param message string +function warn(message, ...) end + +--- +---Calls function `f` with the given arguments in protected mode with a new message handler. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-xpcall"]) +--- +---@param f async fun() +---@param msgh function +---@param arg1? any +---@return boolean success +---@return any result +---@return any ... +function xpcall(f, msgh, arg1, ...) end + +-- ---@version 5.1 +-- --- +-- ---Returns the elements from the given `list`. This function is equivalent to +-- ---```lua +-- --- return list[i], list[i+1], ···, list[j] +-- ---``` +-- --- +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-unpack"]) +-- --- +-- ---@generic T +-- ---@param list T[] +-- ---@param i? integer +-- ---@param j? integer +-- ---@return T ... +-- ---@nodiscard +-- function unpack(list, i, j) end \ No newline at end of file diff --git a/src/EmmyLua/core-builtin-os-api.def.lua b/src/EmmyLua/core-builtin-os-api.def.lua new file mode 100644 index 00000000..04761e2d --- /dev/null +++ b/src/EmmyLua/core-builtin-os-api.def.lua @@ -0,0 +1,186 @@ +---@meta + +--- +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os"]) +--- +---@class oslib +os = {} + +--- +---Returns an approximation of the amount in seconds of CPU time used by the program. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.clock"]) +--- +---@return number +---@nodiscard +function os.clock() end + +---@class osdate +--- +---four digits +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.year"]) +--- +---@field year integer|string +--- +---1-12 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.month"]) +--- +---@field month integer|string +--- +---1-31 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.day"]) +--- +---@field day integer|string +--- +---0-23 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.hour"]) +--- +---@field hour integer|string +--- +---0-59 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.min"]) +--- +---@field min integer|string +--- +---0-61 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.sec"]) +--- +---@field sec integer|string +--- +---weekday, 1–7, Sunday is 1 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.wday"]) +--- +---@field wday integer|string +--- +---day of the year, 1–366 +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.yday"]) +--- +---@field yday integer|string +--- +---daylight saving flag, a boolean +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-osdate.isdst"]) +--- +---@field isdst boolean + +--- +---Returns a string or a table containing date and time, formatted according to the given string `format`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.date"]) +--- +---@param format? string +---@param time? integer +---@return string|osdate +---@nodiscard +function os.date(format, time) end + +--- +---Returns the difference, in seconds, from time `t1` to time `t2`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.difftime"]) +--- +---@param t2 integer +---@param t1 integer +---@return integer +---@nodiscard +function os.difftime(t2, t1) end + +-- --- +-- ---Passes `command` to be executed by an operating system shell. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.execute"]) +-- --- +-- ---@param command? string +-- ---@return boolean? suc +-- ---@return exitcode? exitcode +-- ---@return integer? code +-- function os.execute(command) end + +-- --- +-- ---Calls the ISO C function `exit` to terminate the host program. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.exit"]) +-- --- +-- ---@param code? boolean|integer +-- ---@param close? boolean +-- function os.exit(code, close) end + +-- --- +-- ---Returns the value of the process environment variable `varname`. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.getenv"]) +-- --- +-- ---@param varname string +-- ---@return string? +-- ---@nodiscard +-- function os.getenv(varname) end + +-- --- +-- ---Deletes the file with the given name. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.remove"]) +-- --- +-- ---@param filename string +-- ---@return boolean suc +-- ---@return string? errmsg +-- function os.remove(filename) end + +-- --- +-- ---Renames the file or directory named `oldname` to `newname`. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.rename"]) +-- --- +-- ---@param oldname string +-- ---@param newname string +-- ---@return boolean suc +-- ---@return string? errmsg +-- function os.rename(oldname, newname) end +-- +-- ---@alias localecategory +-- ---|>'"all"' +-- ---| '"collate"' +-- ---| '"ctype"' +-- ---| '"monetary"' +-- ---| '"numeric"' +-- ---| '"time"' + +-- --- +-- ---Sets the current locale of the program. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.setlocale"]) +-- --- +-- ---@param locale string|nil +-- ---@param category? localecategory +-- ---@return string localecategory +-- function os.setlocale(locale, category) end + +--- +---Returns the current time when called without arguments, or a time representing the local date and time specified by the given table. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.time"]) +--- +---@param date? osdate +---@return integer +---@nodiscard +function os.time(date) end + +-- --- +-- ---Returns a string with a file name that can be used for a temporary file. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-os.tmpname"]) +-- --- +-- ---@return string +-- ---@nodiscard +-- function os.tmpname() end + +return os \ No newline at end of file diff --git a/src/EmmyLua/core-builtin-package-api.def.lua b/src/EmmyLua/core-builtin-package-api.def.lua new file mode 100644 index 00000000..77119197 --- /dev/null +++ b/src/EmmyLua/core-builtin-package-api.def.lua @@ -0,0 +1,108 @@ +---@meta + +--- +---Loads the given module, returns any value returned by the searcher(`true` when `nil`). Besides that value, also returns as a second result the loader data returned by the searcher, which indicates how `require` found the module. (For instance, if the module came from a file, this loader data is the file path.) +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-require"]) +--- +---@param modname string +---@return unknown +---@return unknown loaderdata +function require(modname) end + +-- --- +-- --- +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package"]) +-- --- +-- ---@class packagelib +-- --- +-- ---The path used by `require` to search for a C loader. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.cpath"]) +-- --- +-- ---@field cpath string +-- --- +-- ---A table used by `require` to control which modules are already loaded. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.loaded"]) +-- --- +-- ---@field loaded table +-- --- +-- ---The path used by `require` to search for a Lua loader. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.path"]) +-- --- +-- ---@field path string +-- --- +-- ---A table to store loaders for specific modules. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.preload"]) +-- --- +-- ---@field preload table +-- package = {} +-- +-- --- +-- ---A string describing some compile-time configurations for packages. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.config"]) +-- --- +-- package.config = [[ +-- / +-- ; +-- ? +-- ! +-- -]] +-- +-- ---@version <5.1 +-- --- +-- ---A table used by `require` to control how to load modules. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.loaders"]) +-- --- +-- package.loaders = {} +-- +-- --- +-- ---Dynamically links the host program with the C library `libname`. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.loadlib"]) +-- --- +-- ---@param libname string +-- ---@param funcname string +-- ---@return any +-- function package.loadlib(libname, funcname) end +-- +-- --- +-- ---A table used by `require` to control how to load modules. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.searchers"]) +-- --- +-- ---@version >5.2 +-- package.searchers = {} +-- +-- --- +-- ---Searches for the given `name` in the given `path`. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.searchpath"]) +-- --- +-- ---@version >5.2,JIT +-- ---@param name string +-- ---@param path string +-- ---@param sep? string +-- ---@param rep? string +-- ---@return string? filename +-- ---@return string? errmsg +-- ---@nodiscard +-- function package.searchpath(name, path, sep, rep) end +-- +-- --- +-- ---Sets a metatable for `module` with its `__index` field referring to the global environment, so that this module inherits values from the global environment. To be used as an option to function `module` . +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-package.seeall"]) +-- --- +-- ---@version <5.1 +-- ---@param module table +-- function package.seeall(module) end +-- +-- return package +-- \ No newline at end of file diff --git a/src/EmmyLua/core-builtin-string-api.def.lua b/src/EmmyLua/core-builtin-string-api.def.lua new file mode 100644 index 00000000..264ec433 --- /dev/null +++ b/src/EmmyLua/core-builtin-string-api.def.lua @@ -0,0 +1,220 @@ +---@meta + +--- +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string"]) +--- +---@class stringlib +string = {} + +--- +---Returns the internal numeric codes of the characters `s[i], s[i+1], ..., s[j]`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.byte"]) +--- +---@param s string +---@param i? integer +---@param j? integer +---@return integer ... +---@nodiscard +function string.byte(s, i, j) end + +--- +---Returns a string with length equal to the number of arguments, in which each character has the internal numeric code equal to its corresponding argument. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.char"]) +--- +---@param byte integer +---@param ... integer +---@return string +---@nodiscard +function string.char(byte, ...) end + +-- --- +-- ---Returns a string containing a binary representation (a *binary chunk*) of the given function. +-- --- +-- ---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.dump"]) +-- --- +-- ---@param f async fun() +-- ---@param strip? boolean +-- ---@return string +-- ---@nodiscard +-- function string.dump(f, strip) end + +--- +---Looks for the first match of `pattern` (see [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"])) in the string. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.find"]) +--- +---@param s string +---@param pattern string +---@param init? integer +---@param plain? boolean +---@return integer start +---@return integer end +---@return any ... captured +---@nodiscard +function string.find(s, pattern, init, plain) end + +--- +---Returns a formatted version of its variable number of arguments following the description given in its first argument. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.format"]) +--- +---@param s any +---@param ... any +---@return string +---@nodiscard +function string.format(s, ...) end + +--- +---Returns an iterator function that, each time it is called, returns the next captures from `pattern` (see [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"])) over the string s. +--- +---As an example, the following loop will iterate over all the words from string s, printing one per line: +---```lua +--- s = +---"hello world from Lua" +--- for w in string.gmatch(s, "%a+") do +--- print(w) +--- end +---``` +--- +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.gmatch"]) +--- +---@param s string +---@param pattern string +---@param init? integer +---@return fun():string, ... +function string.gmatch(s, pattern, init) end + +--- +---Returns a copy of s in which all (or the first `n`, if given) occurrences of the `pattern` (see [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"])) have been replaced by a replacement string specified by `repl`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.gsub"]) +--- +---@param s string +---@param pattern string +---@param repl string|number|table|function +---@param n? integer +---@return string +---@return integer count +---@nodiscard +function string.gsub(s, pattern, repl, n) end + +--- +---Returns its length. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.len"]) +--- +---@param s string +---@return integer +---@nodiscard +function string.len(s) end + +--- +---Returns a copy of this string with all uppercase letters changed to lowercase. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.lower"]) +--- +---@param s string +---@return string +---@nodiscard +function string.lower(s) end + +--- +---Looks for the first match of `pattern` (see [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"])) in the string. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.match"]) +--- +---@param s string +---@param pattern string +---@param init? integer +---@return any ... +---@nodiscard +function string.match(s, pattern, init) end + +---@version >5.3 +--- +---Returns a binary string containing the values `v1`, `v2`, etc. packed (that is, serialized in binary form) according to the format string `fmt` (see [§6.4.2](command:extension.lua.doc?["en-us/54/manual.html/6.4.2"])) . +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.pack"]) +--- +---@param fmt string +---@param v1 string|number +---@param ... string|number +---@return string binary +---@nodiscard +function string.pack(fmt, v1, v2, ...) end + +---@version >5.3 +--- +---Returns the size of a string resulting from `string.pack` with the given format string `fmt` (see [§6.4.2](command:extension.lua.doc?["en-us/54/manual.html/6.4.2"])) . +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.packsize"]) +--- +---@param fmt string +---@return integer +---@nodiscard +function string.packsize(fmt) end + +--- +---Returns a string that is the concatenation of `n` copies of the string `s` separated by the string `sep`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.rep"]) +--- +---@param s string +---@param n integer +---@param sep? string +---@return string +---@nodiscard +function string.rep(s, n, sep) end + +--- +---Returns a string that is the string `s` reversed. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.reverse"]) +--- +---@param s string +---@return string +---@nodiscard +function string.reverse(s) end + +--- +---Returns the substring of the string that starts at `i` and continues until `j`. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.sub"]) +--- +---@param s string +---@param i integer +---@param j? integer +---@return string +---@nodiscard +function string.sub(s, i, j) end + +---@version >5.3 +--- +---Returns the values packed in string according to the format string `fmt` (see [§6.4.2](command:extension.lua.doc?["en-us/54/manual.html/6.4.2"])) . +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.unpack"]) +--- +---@param fmt string +---@param s string +---@param pos? integer +---@return any ... +---@return integer offset +---@nodiscard +function string.unpack(fmt, s, pos) end + +--- +---Returns a copy of this string with all lowercase letters changed to uppercase. +--- +---[View documents](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.upper"]) +--- +---@param s string +---@return string +---@nodiscard +function string.upper(s) end + +return string \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index ab50421b..901299d5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,22 +1,30 @@ import * as vscode from "vscode"; import * as path from "path"; -export function activate() { +type AnyObject = Record; +const getLuaConfig = () => {return vscode.workspace.getConfiguration("Lua", null);}; + +export function activate(context: vscode.ExtensionContext) { + vscode.window.showInformationMessage("Core Lua API extension activated!"); setExternalLibrary(path.join("out", "EmmyLua"), true); - updateConfig(); + setPreloadSize(); + setBuiltins(context); } export function deactivate() { + vscode.window.showInformationMessage("Core Lua API extension deactivated!"); setExternalLibrary(path.join("out", "EmmyLua"), false); } +/** + * Set the default libraries configuration for the current core project (workspace) + */ export function setExternalLibrary(folder: string, enable: boolean) { console.log("setExternalLibrary", folder, enable); const extensionId = "manticoregames.vscode-core"; const extensionPath = vscode.extensions.getExtension(extensionId)?.extensionPath; const folderPath = extensionPath ? path.join(extensionPath, folder) : ""; - const config = vscode.workspace.getConfiguration("Lua", null); - const library: string[] | undefined = config.get("workspace.library"); + const library: string[] | undefined = getLuaConfig().get("workspace.library"); if (library && extensionPath) { // remove any older versions of our path e.g. "publisher.name-0.0.1" for (let i = library.length - 1; i >= 0; i--) { @@ -38,16 +46,133 @@ export function setExternalLibrary(folder: string, enable: boolean) { library.splice(index, 1); } } - config.update("workspace.library", library, true); + getLuaConfig().update("workspace.library", library); } } -function updateConfig() { - const sumneko = vscode.workspace.getConfiguration("Lua"); - const currentSize: number = sumneko.get("workspace.preloadFileSize") || 150; +/** + * Change the default preload file size configuration for the current core project (workspace) + */ +export function setPreloadSize() { + const currentSize: number = getLuaConfig().get("workspace.preloadFileSize") || 150; if (currentSize < 400) { // increase preloadFileSize to make sure our config gets loaded - sumneko.update("workspace.preloadFileSize", 400, true); + getLuaConfig().update("workspace.preloadFileSize", 400); console.log("Bumping preloadFileSize"); } } + +/** + * Test if two objects have the same members + * @param First First object + * @param Second Second object + * @returns True if they are similar + */ +export function shallowEqual(First : AnyObject | undefined | null, Second : AnyObject | undefined | null) : boolean { + First = First as AnyObject; + Second = Second as AnyObject; + if (!First || !Second) { + return false; + } + const FirstMembers = Object.keys(First); + const SecondMembers = Object.keys(Second); + if (FirstMembers.length !== SecondMembers.length) { + return false; + } + for (const Member of FirstMembers) { + if (First[Member] !== Second[Member]) { + return false; + } + } + return true; +} + +/** + * Change the default builtins configuration for new core project or use the user defined + * Also register the command SetLuaBuiltins (Core Enable/Disable Lua builtins) wich switch between user/core builtins + * @param context The vscode extension context + */ +export function setBuiltins(context: vscode.ExtensionContext) { + const builtinsCmd = 'extension.SetLuaBuiltins'; + const coreBuiltins = { + "basic": "disable", + "io": "disable", + "os": "disable", + "debug": "disable", + "package": "disable", + "string": "disable" + }; + + function getBuiltinState() : AnyObject | undefined { + return context.workspaceState.get('userLuaBuiltins');// || undefined; + } + function updateBuiltinState(value : unknown) { + context.workspaceState.update('userLuaBuiltins', value); + } + + function getBuiltinConfig() : AnyObject | undefined { + return getLuaConfig().get("runtime.builtin"); + } + function updateBuiltinConfig(value : unknown) { + getLuaConfig().update("runtime.builtin", value); + } + + function logBuiltins(bIsConsole: boolean, OptMessage? : string) { + const Msg = `${OptMessage} state:${JSON.stringify(getBuiltinState())}, conf:${JSON.stringify(getBuiltinConfig())}`; + (bIsConsole ? console.log(Msg) : vscode.window.showInformationMessage(Msg)); + } + + function getBuiltinsMsg() : string { + return `state:${JSON.stringify(getBuiltinState())}, conf:${JSON.stringify(getBuiltinConfig())}`; + } + + let count = 0; + function getCounter() : number { + return count++; + } + + let bHasSwitched = false; + function switchBuiltins() { + const preChangeMsg : string = getBuiltinsMsg(); + bHasSwitched = true; + if (shallowEqual(getBuiltinConfig() as AnyObject, coreBuiltins as AnyObject)) { + updateBuiltinConfig(getBuiltinState()); + updateBuiltinState(undefined); + } else { + updateBuiltinState(getBuiltinConfig()); + updateBuiltinConfig(coreBuiltins); + } + logBuiltins(true, `${getCounter()} Switched From: ${preChangeMsg}\n To:`); + } + + // updateBuiltinState(undefined); // simulate first run + logBuiltins(true, `${getCounter()} Initial value`); + // only the first time a project is started and the user has not set builtin config, then we disable sumneko builtins + if (!getBuiltinState() && shallowEqual(getBuiltinConfig() as AnyObject, {} as AnyObject)) { + switchBuiltins(); + } + + const commandDisposable = vscode.commands.registerCommand(builtinsCmd, () => { + switchBuiltins(); + }); + const configEventDisposable = vscode.workspace.onDidChangeConfiguration(event => { + if (event.affectsConfiguration("Lua")) { + console.log("lua change!"); + const preChangeMsg : string = getBuiltinsMsg(); + + if ( (!shallowEqual(getBuiltinState() as AnyObject, getBuiltinConfig() as AnyObject)) && bHasSwitched === false) { + updateBuiltinState(getBuiltinConfig()); + } else if (bHasSwitched === true) { + bHasSwitched = false; + console.log("pp"); + } + logBuiltins(true, `${getCounter()} Changed From: ${preChangeMsg}\n To:`); + } + }); + + context.subscriptions.push( + commandDisposable, + configEventDisposable + ); +} +