Skip to content

Commit

Permalink
Re-add Moonwave doc tags
Browse files Browse the repository at this point in the history
Idk why they weren't there
  • Loading branch information
SignalManSteve authored Jun 27, 2024
1 parent f858ee6 commit df4eff3
Showing 1 changed file with 135 additions and 55 deletions.
190 changes: 135 additions & 55 deletions Cmdr/Shared/Util.lua
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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 = {}

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -106,26 +131,30 @@ 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
return t
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",
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 = {}
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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)

Expand All @@ -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 = {}
Expand All @@ -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
Expand All @@ -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 = {}

Expand Down Expand Up @@ -405,19 +474,26 @@ function Util.MakeAliasCommand(name, commandString)
Description = `<Alias> {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(...)
Expand Down Expand Up @@ -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 = {}

Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit df4eff3

Please sign in to comment.