From 8d402d24ea09aae07d41639211246b67f11f1a86 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 27 Jun 2024 07:19:16 +0100 Subject: [PATCH 1/3] Help Command - Inline Types List data for inline types instead of just 'Unknown (inline argument)' --- Cmdr/BuiltInCommands/help.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Cmdr/BuiltInCommands/help.lua b/Cmdr/BuiltInCommands/help.lua index 6fc4c0c4..699cb4af 100644 --- a/Cmdr/BuiltInCommands/help.lua +++ b/Cmdr/BuiltInCommands/help.lua @@ -44,10 +44,12 @@ return { end if command.Args then for i, arg in ipairs(command.Args) do + if type(arg) == "function" then + arg = arg(arg) + end + context:Reply( - `#{i} {if type(arg) == "table" - then `{arg.Name}{if arg.Optional == true then "?" else ""}: {arg.Type} - {arg.Description}` - else "Unknown (inline argument)"}` + `{arg.Name}{if arg.Optional then "?" else ""}: {if type(arg.Type) == "string" then arg.Type else arg.Type.DisplayName} - {arg.Description}` ) end end From f858ee6e9145196b83c5e4063e79001ca5a1c114 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 27 Jun 2024 07:19:55 +0100 Subject: [PATCH 2/3] Util - MakeEnumType Save the DisplayName field for MakeEnumType so it can be read in the help command --- Cmdr/Shared/Util.lua | 191 +++++++++++++------------------------------ 1 file changed, 56 insertions(+), 135 deletions(-) diff --git a/Cmdr/Shared/Util.lua b/Cmdr/Shared/Util.lua index 58087eb9..00626d55 100644 --- a/Cmdr/Shared/Util.lua +++ b/Cmdr/Shared/Util.lua @@ -1,20 +1,9 @@ local TextService = game:GetService("TextService") ---[=[ - @class Util - - Cmdr utilities module. - - :::info Beta - This page is incomplete and some functions are missing. You might want to refer to [the current documentation](https://eryn.io/Cmdr/api/Util.html). - ::: -]=] local Util = {} ---[=[ - Takes an array and flips its values into dictionary keys with value of true. -]=] -function Util.MakeDictionary(array: { any }): { [any]: true } +--- Takes an array and flips its values into dictionary keys with value of true. +function Util.MakeDictionary(array) local dictionary = {} for i = 1, #array do @@ -24,10 +13,8 @@ function Util.MakeDictionary(array: { any }): { [any]: true } return dictionary end ---[=[ - Takes a dictionary and returns its keys. -]=] -function Util.DictionaryKeys(dict: { [any]: any }): { any } +--- Takes a dictionary and returns its keys. +function Util.DictionaryKeys(dict) local keys = {} for key in pairs(dict) do @@ -48,15 +35,11 @@ local function transformInstanceSet(instances) return names, instances end ---[=[ - Returns a function that is a fuzzy finder for the specified set or container. - - Can pass an array of strings, array of instances, array of EnumItems, - array of dictionaries with a Name key or an instance (in which case its children will be used). - - Exact matches will be inserted in the front of the resulting array. -]=] -function Util.MakeFuzzyFinder(setOrContainer: any): (string, boolean?, boolean?) -> string +--- Returns a function that is a fuzzy finder for the specified set or container. +-- Can pass an array of strings, array of instances, array of EnumItems, +-- array of dictionaries with a Name key or an instance (in which case its children will be used) +-- Exact matches will be inserted in the front of the resulting array +function Util.MakeFuzzyFinder(setOrContainer) local names local instances = {} @@ -76,16 +59,16 @@ function Util.MakeFuzzyFinder(setOrContainer: any): (string, boolean?, boolean?) elseif type(setOrContainer[1]) == "string" then names = setOrContainer elseif setOrContainer[1] ~= nil then - error("[Cmdr] MakeFuzzyFinder only accepts tables of instances or strings.") + error("MakeFuzzyFinder only accepts tables of instances or strings.") else names = {} end else - error("[Cmdr] MakeFuzzyFinder only accepts a table, Enum, or Instance.") + error("MakeFuzzyFinder only accepts a table, Enum, or Instance.") end -- Searches the set (checking exact matches first) - return function(text: string, returnFirst: boolean?, matchStart: boolean?) + return function(text, returnFirst) local results = {} for i, name in pairs(names) do @@ -99,10 +82,6 @@ function Util.MakeFuzzyFinder(setOrContainer: any): (string, boolean?, boolean?) else table.insert(results, 1, value) end - elseif matchStart then - if name:lower():sub(1, #text) == text:lower() then - results[#results + 1] = value - end elseif name:lower():find(text:lower(), 1, true) then results[#results + 1] = value end @@ -116,12 +95,8 @@ function Util.MakeFuzzyFinder(setOrContainer: any): (string, boolean?, boolean?) end end ---[=[ - Takes an array of instances (or anything with a Name property) and maps them into an array of their names. - - If no Name property is present, then tostring will be called instead. -]=] -function Util.GetNames(instances: any): { string } +--- Takes an array of instances and returns an array of those instances' names. +function Util.GetNames(instances) local names = {} for i = 1, #instances do @@ -131,16 +106,14 @@ function Util.GetNames(instances: any): { string } return names end ---[=[ - Splits a string using a simple separator (no quote parsing) -]=] -function Util.SplitStringSimple(input: string, sep: string?): { string } +--- Splits a string using a simple separator (no quote parsing) +function Util.SplitStringSimple(inputstr, sep) if sep == nil then sep = "%s" end local t = {} local i = 1 - for str in string.gmatch(input, "([^" .. (sep :: string) .. "]+)") do + for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do t[i] = str i = i + 1 end @@ -148,13 +121,11 @@ function Util.SplitStringSimple(input: string, sep: string?): { string } end local function charCode(n) - return utf8.char(tonumber(n, 16) :: number) + return utf8.char(tonumber(n, 16)) end ---[=[ - Parses escape sequences into their fully qualified characters -]=] -function Util.ParseEscapeSequences(text: string): string +--- Parses escape sequences into their fully qualified characters +function Util.ParseEscapeSequences(text) return text:gsub("\\(.)", { t = "\t", n = "\n", @@ -163,10 +134,7 @@ function Util.ParseEscapeSequences(text: string): string :gsub("\\x(%x%x)", charCode) end ---[=[ - No description. -]=] -function Util.EncodeEscapedOperator(text: string, op: string): string +function Util.EncodeEscapedOperator(text, op) local first = op:sub(1, 1) local escapedOp = op:gsub(".", "%%%1") local escapedFirst = "%" .. first @@ -179,10 +147,7 @@ function Util.EncodeEscapedOperator(text: string, op: string): string end local OPERATORS = { "&&", "||", ";" } ---[=[ - No description. -]=] -function Util.EncodeEscapedOperators(text: string): string +function Util.EncodeEscapedOperators(text) for _, operator in ipairs(OPERATORS) do text = Util.EncodeEscapedOperator(text, operator) end @@ -203,10 +168,8 @@ local function decodeControlChars(text) return (text:gsub("___!CMDR_ESCAPE!___", "\\"):gsub("___!CMDR_QUOTE!___", '"'):gsub("___!CMDR_NL!___", "\n")) end ---[=[ - Splits a string by space but taking into account quoted sequences which will be treated as a single argument. -]=] -function Util.SplitString(text: string, max: number): { string } +--- Splits a string by space but taking into account quoted sequences which will be treated as a single argument. +function Util.SplitString(text, max) text = encodeControlChars(text) max = max or math.huge local t = {} @@ -236,10 +199,9 @@ function Util.SplitString(text: string, max: number): { string } return t end ---[=[ - Takes an array of arguments and a max value. Any indicies past the max value will be appended to the last valid argument. -]=] -function Util.MashExcessArguments(arguments: { string }, max: number): { string } +--- Takes an array of arguments and a max value. +-- Any indicies past the max value will be appended to the last valid argument. +function Util.MashExcessArguments(arguments, max) local t = {} for i = 1, #arguments do if i > max then @@ -251,29 +213,23 @@ function Util.MashExcessArguments(arguments: { string }, max: number): { string return t end ---[=[ - Trims whitespace from both sides of a string. -]=] -function Util.TrimString(str: string): string +--- Trims whitespace from both sides of a string. +function Util.TrimString(str) local _, from = string.find(str, "^%s*") -- trim the string in two steps to prevent quadratic backtracking when no "%S" match is found return from == #str and "" or string.match(str, ".*%S", from + 1) end ---[=[ - Returns the text bounds size based on given text, label (from which properties will be pulled), and optional Vector2 container size. -]=] -function Util.GetTextSize(text: string, label: TextLabel, size: Vector2?): Vector2 +--- Returns the text bounds size based on given text, label (from which properties will be pulled), and optional Vector2 container size. +function Util.GetTextSize(text, label, size) return TextService:GetTextSize(text, label.TextSize, label.Font, size or Vector2.new(label.AbsoluteSize.X, 0)) end ---[=[ - Makes an Enum type. - @return TypeDefinition -]=] -function Util.MakeEnumType(name: string, values: any) +--- Makes an Enum type. +function Util.MakeEnumType(name, values) local findValue = Util.MakeFuzzyFinder(values) return { + DisplayName = name, Validate = function(text) return findValue(text, true) ~= nil, ("Value %q is not a valid %s."):format(text, name) end, @@ -287,10 +243,8 @@ function Util.MakeEnumType(name: string, values: any) } end ---[=[ - Parses a prefixed union type argument (such as %Team) -]=] -function Util.ParsePrefixedUnionType(typeValue: string, rawValue: string): (string?, string?, string?) +--- Parses a prefixed union type argument (such as %Team) +function Util.ParsePrefixedUnionType(typeValue, rawValue) local split = Util.SplitStringSimple(typeValue) -- Check prefixes in order from longest to shortest @@ -313,15 +267,9 @@ function Util.ParsePrefixedUnionType(typeValue: string, rawValue: string): (stri return t.type, rawValue:sub(#t.prefix + 1), t.prefix end end - return end ---[=[ - Creates a listable type from a singular type - @param type TypeDefinition - @param override table - @return TypeDefinition -]=] +--- Creates a listable type from a singlular type function Util.MakeListableType(type, override) local listableType = { Listable = true, @@ -353,12 +301,7 @@ local function decodeCommandEscape(text) return (text:gsub("___!CMDR_DOLLAR!___", "$")) end ---[=[ - Creates a listable type from a singular type - @param dispatcher Dispatcher - @return string? -- output from Dispatcher:EvaluateAndRun as a string -]=] -function Util.RunCommandString(dispatcher, commandString: string): string? +function Util.RunCommandString(dispatcher, commandString) commandString = Util.ParseEscapeSequences(commandString) commandString = Util.EncodeEscapedOperators(commandString) @@ -375,15 +318,10 @@ function Util.RunCommandString(dispatcher, commandString: string): string? return output end end - return end ---[=[ - Runs embedded commands and replaces them - @param dispatcher Dispatcher - @param str string -]=] -function Util.RunEmbeddedCommands(dispatcher, str): string +--- Runs embedded commands and replaces them +function Util.RunEmbeddedCommands(dispatcher, str) str = encodeCommandEscape(str) local results = {} @@ -409,12 +347,9 @@ function Util.RunEmbeddedCommands(dispatcher, str): string return decodeCommandEscape(str:gsub("$(%b{})", results)) end ---[=[ - Replaces arguments in the format $1, $2, $something with whatever the given function returns for it. - @param str string - @param replace string -]=] -function Util.SubstituteArgs(str, replace): string +--- Replaces arguments in the format $1, $2, $something with whatever the +-- given function returns for it. +function Util.SubstituteArgs(str, replace) str = encodeCommandEscape(str) -- Convert numerical keys to strings if type(replace) == "table" then @@ -430,11 +365,8 @@ function Util.SubstituteArgs(str, replace): string return decodeCommandEscape(str:gsub("($%d+)%b{}", "%1"):gsub("$(%w+)", replace)) end ---[=[ - Creates an alias command, should only be used on the client. - @return CommandDefinition -]=] -function Util.MakeAliasCommand(name: string, commandString: string) +--- Creates an alias command +function Util.MakeAliasCommand(name, commandString) local commandName, commandDescription = unpack(name:split("|")) local args = {} @@ -473,26 +405,19 @@ function Util.MakeAliasCommand(name: string, commandString: string) Description = ` {commandDescription or commandString}`, Group = "UserAlias", Args = args, - ClientRun = function(context) + Run = function(context) return Util.RunCommandString(context.Dispatcher, Util.SubstituteArgs(commandString, context.RawArguments)) end, } end ---[=[ - Makes a type that contains a sequence, e.g. Vector3 or Color3 - - For options, one of Constructor or Parse is required - - @param options { Parse: function?, Constructor: function?, TransformEach: function?, ValidateEach: function?, Prefixes: {string}?, Length: number? } - @return ArgumentDefinition -]=] +--- Makes a type that contains a sequence, e.g. Vector3 or Color3 function Util.MakeSequenceType(options) options = options or {} assert( options.Parse ~= nil or options.Constructor ~= nil, - "[Cmdr] MakeSequenceType: Must provide one of: Constructor, Parse" + "MakeSequenceType: Must provide one of: Constructor, Parse" ) options.TransformEach = options.TransformEach or function(...) @@ -534,21 +459,17 @@ function Util.MakeSequenceType(options) } end ---[=[ - Splits a string by a single delimeter chosen from the given set. The first matching delimeter from the set becomes the split character. -]=] -function Util.SplitPrioritizedDelimeter(text: string, delimiters: { string }): { string }? - for i, delimeter in ipairs(delimiters) do - if text:find(delimeter) or i == #delimiters then +--- Splits a string by a single delimeter chosen from the given set. +-- The first matching delimeter from the set becomes the split character. +function Util.SplitPrioritizedDelimeter(text, delimeters) + for i, delimeter in ipairs(delimeters) do + if text:find(delimeter) or i == #delimeters then return Util.SplitStringSimple(text, delimeter) end end - return end --- TODO: Continue documentation from here down - --- Maps values of an array through a callback and returns an array of mapped values. +--- Maps values of an array through a callback and returns an array of mapped values function Util.Map(array, callback) local results = {} @@ -559,7 +480,7 @@ function Util.Map(array, callback) return results end --- Maps arguments #2-n through callback and returns values as tuple +--- Maps arguments #2-n through callback and returns values as tuple function Util.Each(callback, ...) local results = {} for i, value in ipairs({ ... }) do @@ -568,7 +489,7 @@ function Util.Each(callback, ...) return unpack(results) end --- Emulates tabstops with spaces +--- Emulates tabstops with spaces function Util.EmulateTabstops(text, tabWidth) local column = 0 local textLength = #text From df4eff3b2638116870c1c26f59ebdb431025e1b3 Mon Sep 17 00:00:00 2001 From: Tom <54591857+SignalManSteve@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:43:52 +0100 Subject: [PATCH 3/3] Re-add Moonwave doc tags Idk why they weren't there --- Cmdr/Shared/Util.lua | 190 ++++++++++++++++++++++++++++++------------- 1 file changed, 135 insertions(+), 55 deletions(-) diff --git a/Cmdr/Shared/Util.lua b/Cmdr/Shared/Util.lua index 00626d55..ea4d5049 100644 --- a/Cmdr/Shared/Util.lua +++ b/Cmdr/Shared/Util.lua @@ -1,9 +1,20 @@ local TextService = game:GetService("TextService") +--[=[ + @class Util + + Cmdr utilities module. + + :::info Beta + This page is incomplete and some functions are missing. You might want to refer to [the current documentation](https://eryn.io/Cmdr/api/Util.html). + ::: +]=] local Util = {} ---- Takes an array and flips its values into dictionary keys with value of true. -function Util.MakeDictionary(array) +--[=[ + Takes an array and flips its values into dictionary keys with value of true. +]=] +function Util.MakeDictionary(array: { any }): { [any]: true } local dictionary = {} for i = 1, #array do @@ -13,8 +24,10 @@ function Util.MakeDictionary(array) return dictionary end ---- Takes a dictionary and returns its keys. -function Util.DictionaryKeys(dict) +--[=[ + Takes a dictionary and returns its keys. +]=] +function Util.DictionaryKeys(dict: { [any]: any }): { any } local keys = {} for key in pairs(dict) do @@ -35,11 +48,15 @@ local function transformInstanceSet(instances) return names, instances end ---- Returns a function that is a fuzzy finder for the specified set or container. --- Can pass an array of strings, array of instances, array of EnumItems, --- array of dictionaries with a Name key or an instance (in which case its children will be used) --- Exact matches will be inserted in the front of the resulting array -function Util.MakeFuzzyFinder(setOrContainer) +--[=[ + Returns a function that is a fuzzy finder for the specified set or container. + + Can pass an array of strings, array of instances, array of EnumItems, + array of dictionaries with a Name key or an instance (in which case its children will be used). + + Exact matches will be inserted in the front of the resulting array. +]=] +function Util.MakeFuzzyFinder(setOrContainer: any): (string, boolean?, boolean?) -> string local names local instances = {} @@ -59,16 +76,16 @@ function Util.MakeFuzzyFinder(setOrContainer) elseif type(setOrContainer[1]) == "string" then names = setOrContainer elseif setOrContainer[1] ~= nil then - error("MakeFuzzyFinder only accepts tables of instances or strings.") + error("[Cmdr] MakeFuzzyFinder only accepts tables of instances or strings.") else names = {} end else - error("MakeFuzzyFinder only accepts a table, Enum, or Instance.") + error("[Cmdr] MakeFuzzyFinder only accepts a table, Enum, or Instance.") end -- Searches the set (checking exact matches first) - return function(text, returnFirst) + return function(text: string, returnFirst: boolean?, matchStart: boolean?) local results = {} for i, name in pairs(names) do @@ -82,6 +99,10 @@ function Util.MakeFuzzyFinder(setOrContainer) else table.insert(results, 1, value) end + elseif matchStart then + if name:lower():sub(1, #text) == text:lower() then + results[#results + 1] = value + end elseif name:lower():find(text:lower(), 1, true) then results[#results + 1] = value end @@ -95,8 +116,12 @@ function Util.MakeFuzzyFinder(setOrContainer) end end ---- Takes an array of instances and returns an array of those instances' names. -function Util.GetNames(instances) +--[=[ + Takes an array of instances (or anything with a Name property) and maps them into an array of their names. + + If no Name property is present, then tostring will be called instead. +]=] +function Util.GetNames(instances: any): { string } local names = {} for i = 1, #instances do @@ -106,14 +131,16 @@ function Util.GetNames(instances) return names end ---- Splits a string using a simple separator (no quote parsing) -function Util.SplitStringSimple(inputstr, sep) +--[=[ + Splits a string using a simple separator (no quote parsing) +]=] +function Util.SplitStringSimple(input: string, sep: string?): { string } if sep == nil then sep = "%s" end local t = {} local i = 1 - for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do + for str in string.gmatch(input, "([^" .. (sep :: string) .. "]+)") do t[i] = str i = i + 1 end @@ -121,11 +148,13 @@ function Util.SplitStringSimple(inputstr, sep) end local function charCode(n) - return utf8.char(tonumber(n, 16)) + return utf8.char(tonumber(n, 16) :: number) end ---- Parses escape sequences into their fully qualified characters -function Util.ParseEscapeSequences(text) +--[=[ + Parses escape sequences into their fully qualified characters +]=] +function Util.ParseEscapeSequences(text: string): string return text:gsub("\\(.)", { t = "\t", n = "\n", @@ -134,7 +163,10 @@ function Util.ParseEscapeSequences(text) :gsub("\\x(%x%x)", charCode) end -function Util.EncodeEscapedOperator(text, op) +--[=[ + No description. +]=] +function Util.EncodeEscapedOperator(text: string, op: string): string local first = op:sub(1, 1) local escapedOp = op:gsub(".", "%%%1") local escapedFirst = "%" .. first @@ -147,7 +179,10 @@ function Util.EncodeEscapedOperator(text, op) end local OPERATORS = { "&&", "||", ";" } -function Util.EncodeEscapedOperators(text) +--[=[ + No description. +]=] +function Util.EncodeEscapedOperators(text: string): string for _, operator in ipairs(OPERATORS) do text = Util.EncodeEscapedOperator(text, operator) end @@ -168,8 +203,10 @@ local function decodeControlChars(text) return (text:gsub("___!CMDR_ESCAPE!___", "\\"):gsub("___!CMDR_QUOTE!___", '"'):gsub("___!CMDR_NL!___", "\n")) end ---- Splits a string by space but taking into account quoted sequences which will be treated as a single argument. -function Util.SplitString(text, max) +--[=[ + Splits a string by space but taking into account quoted sequences which will be treated as a single argument. +]=] +function Util.SplitString(text: string, max: number): { string } text = encodeControlChars(text) max = max or math.huge local t = {} @@ -199,9 +236,10 @@ function Util.SplitString(text, max) return t end ---- Takes an array of arguments and a max value. --- Any indicies past the max value will be appended to the last valid argument. -function Util.MashExcessArguments(arguments, max) +--[=[ + Takes an array of arguments and a max value. Any indicies past the max value will be appended to the last valid argument. +]=] +function Util.MashExcessArguments(arguments: { string }, max: number): { string } local t = {} for i = 1, #arguments do if i > max then @@ -213,20 +251,27 @@ function Util.MashExcessArguments(arguments, max) return t end ---- Trims whitespace from both sides of a string. -function Util.TrimString(str) +--[=[ + Trims whitespace from both sides of a string. +]=] +function Util.TrimString(str: string): string local _, from = string.find(str, "^%s*") -- trim the string in two steps to prevent quadratic backtracking when no "%S" match is found return from == #str and "" or string.match(str, ".*%S", from + 1) end ---- Returns the text bounds size based on given text, label (from which properties will be pulled), and optional Vector2 container size. -function Util.GetTextSize(text, label, size) +--[=[ + Returns the text bounds size based on given text, label (from which properties will be pulled), and optional Vector2 container size. +]=] +function Util.GetTextSize(text: string, label: TextLabel, size: Vector2?): Vector2 return TextService:GetTextSize(text, label.TextSize, label.Font, size or Vector2.new(label.AbsoluteSize.X, 0)) end ---- Makes an Enum type. -function Util.MakeEnumType(name, values) +--[=[ + Makes an Enum type. + @return TypeDefinition +]=] +function Util.MakeEnumType(name: string, values: any) local findValue = Util.MakeFuzzyFinder(values) return { DisplayName = name, @@ -243,8 +288,10 @@ function Util.MakeEnumType(name, values) } end ---- Parses a prefixed union type argument (such as %Team) -function Util.ParsePrefixedUnionType(typeValue, rawValue) +--[=[ + Parses a prefixed union type argument (such as %Team) +]=] +function Util.ParsePrefixedUnionType(typeValue: string, rawValue: string): (string?, string?, string?) local split = Util.SplitStringSimple(typeValue) -- Check prefixes in order from longest to shortest @@ -267,9 +314,15 @@ function Util.ParsePrefixedUnionType(typeValue, rawValue) return t.type, rawValue:sub(#t.prefix + 1), t.prefix end end + return end ---- Creates a listable type from a singlular type +--[=[ + Creates a listable type from a singular type + @param type TypeDefinition + @param override table + @return TypeDefinition +]=] function Util.MakeListableType(type, override) local listableType = { Listable = true, @@ -301,7 +354,12 @@ local function decodeCommandEscape(text) return (text:gsub("___!CMDR_DOLLAR!___", "$")) end -function Util.RunCommandString(dispatcher, commandString) +--[=[ + Creates a listable type from a singular type + @param dispatcher Dispatcher + @return string? -- output from Dispatcher:EvaluateAndRun as a string +]=] +function Util.RunCommandString(dispatcher, commandString: string): string? commandString = Util.ParseEscapeSequences(commandString) commandString = Util.EncodeEscapedOperators(commandString) @@ -318,10 +376,15 @@ function Util.RunCommandString(dispatcher, commandString) return output end end + return end ---- Runs embedded commands and replaces them -function Util.RunEmbeddedCommands(dispatcher, str) +--[=[ + Runs embedded commands and replaces them + @param dispatcher Dispatcher + @param str string +]=] +function Util.RunEmbeddedCommands(dispatcher, str): string str = encodeCommandEscape(str) local results = {} @@ -347,9 +410,12 @@ function Util.RunEmbeddedCommands(dispatcher, str) return decodeCommandEscape(str:gsub("$(%b{})", results)) end ---- Replaces arguments in the format $1, $2, $something with whatever the --- given function returns for it. -function Util.SubstituteArgs(str, replace) +--[=[ + Replaces arguments in the format $1, $2, $something with whatever the given function returns for it. + @param str string + @param replace string +]=] +function Util.SubstituteArgs(str, replace): string str = encodeCommandEscape(str) -- Convert numerical keys to strings if type(replace) == "table" then @@ -365,8 +431,11 @@ function Util.SubstituteArgs(str, replace) return decodeCommandEscape(str:gsub("($%d+)%b{}", "%1"):gsub("$(%w+)", replace)) end ---- Creates an alias command -function Util.MakeAliasCommand(name, commandString) +--[=[ + Creates an alias command, should only be used on the client. + @return CommandDefinition +]=] +function Util.MakeAliasCommand(name: string, commandString: string) local commandName, commandDescription = unpack(name:split("|")) local args = {} @@ -405,19 +474,26 @@ function Util.MakeAliasCommand(name, commandString) Description = ` {commandDescription or commandString}`, Group = "UserAlias", Args = args, - Run = function(context) + ClientRun = function(context) return Util.RunCommandString(context.Dispatcher, Util.SubstituteArgs(commandString, context.RawArguments)) end, } end ---- Makes a type that contains a sequence, e.g. Vector3 or Color3 +--[=[ + Makes a type that contains a sequence, e.g. Vector3 or Color3 + + For options, one of Constructor or Parse is required + + @param options { Parse: function?, Constructor: function?, TransformEach: function?, ValidateEach: function?, Prefixes: {string}?, Length: number? } + @return ArgumentDefinition +]=] function Util.MakeSequenceType(options) options = options or {} assert( options.Parse ~= nil or options.Constructor ~= nil, - "MakeSequenceType: Must provide one of: Constructor, Parse" + "[Cmdr] MakeSequenceType: Must provide one of: Constructor, Parse" ) options.TransformEach = options.TransformEach or function(...) @@ -459,17 +535,21 @@ function Util.MakeSequenceType(options) } end ---- Splits a string by a single delimeter chosen from the given set. --- The first matching delimeter from the set becomes the split character. -function Util.SplitPrioritizedDelimeter(text, delimeters) - for i, delimeter in ipairs(delimeters) do - if text:find(delimeter) or i == #delimeters then +--[=[ + Splits a string by a single delimeter chosen from the given set. The first matching delimeter from the set becomes the split character. +]=] +function Util.SplitPrioritizedDelimeter(text: string, delimiters: { string }): { string }? + for i, delimeter in ipairs(delimiters) do + if text:find(delimeter) or i == #delimiters then return Util.SplitStringSimple(text, delimeter) end end + return end ---- Maps values of an array through a callback and returns an array of mapped values +-- TODO: Continue documentation from here down + +-- Maps values of an array through a callback and returns an array of mapped values. function Util.Map(array, callback) local results = {} @@ -480,7 +560,7 @@ function Util.Map(array, callback) return results end ---- Maps arguments #2-n through callback and returns values as tuple +-- Maps arguments #2-n through callback and returns values as tuple function Util.Each(callback, ...) local results = {} for i, value in ipairs({ ... }) do @@ -489,7 +569,7 @@ function Util.Each(callback, ...) return unpack(results) end ---- Emulates tabstops with spaces +-- Emulates tabstops with spaces function Util.EmulateTabstops(text, tabWidth) local column = 0 local textLength = #text