@trioforge/brigadier 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +73 -2
- package/out/arguments.d.ts +91 -0
- package/out/arguments.luau +475 -0
- package/out/command-dispatcher.d.ts +38 -0
- package/out/command-dispatcher.luau +394 -0
- package/out/command.d.ts +13 -0
- package/out/command.luau +8 -0
- package/out/context.d.ts +121 -0
- package/out/context.luau +576 -0
- package/out/exceptions.d.ts +118 -0
- package/out/exceptions.luau +415 -0
- package/out/index.d.ts +10 -0
- package/out/init.luau +44 -0
- package/out/java.d.ts +40 -0
- package/out/java.luau +424 -0
- package/out/literal-message.d.ts +9 -0
- package/out/literal-message.luau +29 -0
- package/out/string-reader.d.ts +41 -0
- package/out/string-reader.luau +271 -0
- package/out/suggestion.d.ts +60 -0
- package/out/suggestion.luau +340 -0
- package/out/tree.d.ts +126 -0
- package/out/tree.luau +579 -0
- package/package.json +33 -5
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _context = TS.import(script, script.Parent, "context")
|
|
4
|
+
local CommandContextBuilder = _context.CommandContextBuilder
|
|
5
|
+
local ContextChain = _context.ContextChain
|
|
6
|
+
local CommandSyntaxException = TS.import(script, script.Parent, "exceptions").CommandSyntaxException
|
|
7
|
+
local _java = TS.import(script, script.Parent, "java")
|
|
8
|
+
local rethrow = _java.rethrow
|
|
9
|
+
local stableSort = _java.stableSort
|
|
10
|
+
local substring = _java.substring
|
|
11
|
+
local toLowerCase = _java.toLowerCase
|
|
12
|
+
local StringReader = TS.import(script, script.Parent, "string-reader").StringReader
|
|
13
|
+
local _suggestion = TS.import(script, script.Parent, "suggestion")
|
|
14
|
+
local Suggestions = _suggestion.Suggestions
|
|
15
|
+
local SuggestionsBuilder = _suggestion.SuggestionsBuilder
|
|
16
|
+
local RootCommandNode = TS.import(script, script.Parent, "tree").RootCommandNode
|
|
17
|
+
local ParseResults
|
|
18
|
+
do
|
|
19
|
+
ParseResults = setmetatable({}, {
|
|
20
|
+
__tostring = function()
|
|
21
|
+
return "ParseResults"
|
|
22
|
+
end,
|
|
23
|
+
})
|
|
24
|
+
ParseResults.__index = ParseResults
|
|
25
|
+
function ParseResults.new(...)
|
|
26
|
+
local self = setmetatable({}, ParseResults)
|
|
27
|
+
return self:constructor(...) or self
|
|
28
|
+
end
|
|
29
|
+
function ParseResults:constructor(context, reader, exceptions)
|
|
30
|
+
self.context = context
|
|
31
|
+
self.reader = reader or StringReader.new("")
|
|
32
|
+
self.exceptions = exceptions or {}
|
|
33
|
+
end
|
|
34
|
+
function ParseResults:getContext()
|
|
35
|
+
return self.context
|
|
36
|
+
end
|
|
37
|
+
function ParseResults:getReader()
|
|
38
|
+
return self.reader
|
|
39
|
+
end
|
|
40
|
+
function ParseResults:getExceptions()
|
|
41
|
+
return self.exceptions
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
local ARGUMENT_SEPARATOR = " "
|
|
45
|
+
local USAGE_OPTIONAL_OPEN = "["
|
|
46
|
+
local USAGE_OPTIONAL_CLOSE = "]"
|
|
47
|
+
local USAGE_REQUIRED_OPEN = "("
|
|
48
|
+
local USAGE_REQUIRED_CLOSE = ")"
|
|
49
|
+
local USAGE_OR = "|"
|
|
50
|
+
local function ignoreResult()
|
|
51
|
+
end
|
|
52
|
+
-- The message of an error that isn't a CommandSyntaxException, as RuntimeException.getMessage gives it.
|
|
53
|
+
local function messageOf(err)
|
|
54
|
+
local _err = err
|
|
55
|
+
local _condition = type(_err) == "table"
|
|
56
|
+
if _condition then
|
|
57
|
+
local _getMessage = err.getMessage
|
|
58
|
+
_condition = type(_getMessage) == "function"
|
|
59
|
+
end
|
|
60
|
+
if _condition then
|
|
61
|
+
return err:getMessage()
|
|
62
|
+
end
|
|
63
|
+
return tostring(err)
|
|
64
|
+
end
|
|
65
|
+
local function hasCommandSyntaxExceptions(parse)
|
|
66
|
+
return not (next(parse:getExceptions()) == nil)
|
|
67
|
+
end
|
|
68
|
+
local function compareParses(a, b)
|
|
69
|
+
if not a:getReader():canRead() and b:getReader():canRead() then
|
|
70
|
+
return -1
|
|
71
|
+
end
|
|
72
|
+
if a:getReader():canRead() and not b:getReader():canRead() then
|
|
73
|
+
return 1
|
|
74
|
+
end
|
|
75
|
+
if not hasCommandSyntaxExceptions(a) and hasCommandSyntaxExceptions(b) then
|
|
76
|
+
return -1
|
|
77
|
+
end
|
|
78
|
+
if hasCommandSyntaxExceptions(a) and not hasCommandSyntaxExceptions(b) then
|
|
79
|
+
return 1
|
|
80
|
+
end
|
|
81
|
+
return 0
|
|
82
|
+
end
|
|
83
|
+
local CommandDispatcher
|
|
84
|
+
do
|
|
85
|
+
CommandDispatcher = setmetatable({}, {
|
|
86
|
+
__tostring = function()
|
|
87
|
+
return "CommandDispatcher"
|
|
88
|
+
end,
|
|
89
|
+
})
|
|
90
|
+
CommandDispatcher.__index = CommandDispatcher
|
|
91
|
+
function CommandDispatcher.new(...)
|
|
92
|
+
local self = setmetatable({}, CommandDispatcher)
|
|
93
|
+
return self:constructor(...) or self
|
|
94
|
+
end
|
|
95
|
+
function CommandDispatcher:constructor(root)
|
|
96
|
+
self.consumer = ignoreResult
|
|
97
|
+
self.root = root or RootCommandNode.new()
|
|
98
|
+
end
|
|
99
|
+
function CommandDispatcher:register(command)
|
|
100
|
+
local build = command:build()
|
|
101
|
+
self.root:addChild(build)
|
|
102
|
+
return build
|
|
103
|
+
end
|
|
104
|
+
function CommandDispatcher:setConsumer(consumer)
|
|
105
|
+
self.consumer = consumer
|
|
106
|
+
end
|
|
107
|
+
function CommandDispatcher:execute(input, source)
|
|
108
|
+
if TS.instanceof(input, ParseResults) then
|
|
109
|
+
return self:executeParse(input)
|
|
110
|
+
end
|
|
111
|
+
return self:executeParse(self:parse(input, source))
|
|
112
|
+
end
|
|
113
|
+
function CommandDispatcher:executeParse(parse)
|
|
114
|
+
if parse:getReader():canRead() then
|
|
115
|
+
local exceptions = parse:getExceptions()
|
|
116
|
+
-- ▼ ReadonlyMap.size ▼
|
|
117
|
+
local _size = 0
|
|
118
|
+
for _ in exceptions do
|
|
119
|
+
_size += 1
|
|
120
|
+
end
|
|
121
|
+
-- ▲ ReadonlyMap.size ▲
|
|
122
|
+
if _size == 1 then
|
|
123
|
+
for _, exception in exceptions do
|
|
124
|
+
error(exception)
|
|
125
|
+
end
|
|
126
|
+
elseif parse:getContext():getRange():isEmpty() then
|
|
127
|
+
error(CommandSyntaxException.BUILT_IN_EXCEPTIONS:dispatcherUnknownCommand():createWithContext(parse:getReader()))
|
|
128
|
+
end
|
|
129
|
+
error(CommandSyntaxException.BUILT_IN_EXCEPTIONS:dispatcherUnknownArgument():createWithContext(parse:getReader()))
|
|
130
|
+
end
|
|
131
|
+
local command = parse:getReader():getString()
|
|
132
|
+
local original = parse:getContext():build(command)
|
|
133
|
+
local flatContext = ContextChain:tryFlatten(original)
|
|
134
|
+
if flatContext == nil then
|
|
135
|
+
self.consumer(original, false, 0)
|
|
136
|
+
error(CommandSyntaxException.BUILT_IN_EXCEPTIONS:dispatcherUnknownCommand():createWithContext(parse:getReader()))
|
|
137
|
+
end
|
|
138
|
+
return flatContext:executeAll(original:getSource(), self.consumer)
|
|
139
|
+
end
|
|
140
|
+
function CommandDispatcher:parse(command, source)
|
|
141
|
+
local _command = command
|
|
142
|
+
local reader = if type(_command) == "string" then StringReader.new(command) else command
|
|
143
|
+
local context = CommandContextBuilder.new(self, source, self.root, reader:getCursor())
|
|
144
|
+
return self:parseNodes(self.root, reader, context)
|
|
145
|
+
end
|
|
146
|
+
function CommandDispatcher:parseNodes(node, originalReader, contextSoFar)
|
|
147
|
+
local source = contextSoFar:getSource()
|
|
148
|
+
local errors
|
|
149
|
+
local potentials
|
|
150
|
+
local cursor = originalReader:getCursor()
|
|
151
|
+
for _, child in node:getRelevantNodes(originalReader) do
|
|
152
|
+
if not child:canUse(source) then
|
|
153
|
+
continue
|
|
154
|
+
end
|
|
155
|
+
local context = contextSoFar:copy()
|
|
156
|
+
local reader = StringReader.new(originalReader)
|
|
157
|
+
local exception
|
|
158
|
+
TS.try(function()
|
|
159
|
+
child:parse(reader, context)
|
|
160
|
+
if reader:canRead() and reader:peek() ~= ARGUMENT_SEPARATOR then
|
|
161
|
+
exception = CommandSyntaxException.BUILT_IN_EXCEPTIONS:dispatcherExpectedArgumentSeparator():createWithContext(reader)
|
|
162
|
+
end
|
|
163
|
+
end, function(err)
|
|
164
|
+
exception = if TS.instanceof(err, CommandSyntaxException) then err else CommandSyntaxException.BUILT_IN_EXCEPTIONS:dispatcherParseException():createWithContext(reader, messageOf(err))
|
|
165
|
+
end)
|
|
166
|
+
if exception ~= nil then
|
|
167
|
+
if errors == nil then
|
|
168
|
+
errors = {}
|
|
169
|
+
end
|
|
170
|
+
local _errors = errors
|
|
171
|
+
local _exception = exception
|
|
172
|
+
_errors[child] = _exception
|
|
173
|
+
reader:setCursor(cursor)
|
|
174
|
+
continue
|
|
175
|
+
end
|
|
176
|
+
context:withCommand(child:getCommand())
|
|
177
|
+
local redirect = child:getRedirect()
|
|
178
|
+
if reader:canRead(if redirect == nil then 2 else 1) then
|
|
179
|
+
reader:skip()
|
|
180
|
+
if redirect ~= nil then
|
|
181
|
+
local childContext = CommandContextBuilder.new(self, source, redirect, reader:getCursor())
|
|
182
|
+
local parse = self:parseNodes(redirect, reader, childContext)
|
|
183
|
+
context:withChild(parse:getContext())
|
|
184
|
+
return ParseResults.new(context, parse:getReader(), parse:getExceptions())
|
|
185
|
+
end
|
|
186
|
+
local parse = self:parseNodes(child, reader, context)
|
|
187
|
+
if potentials == nil then
|
|
188
|
+
potentials = {}
|
|
189
|
+
end
|
|
190
|
+
table.insert(potentials, parse)
|
|
191
|
+
else
|
|
192
|
+
if potentials == nil then
|
|
193
|
+
potentials = {}
|
|
194
|
+
end
|
|
195
|
+
local _potentials = potentials
|
|
196
|
+
local _parseResults = ParseResults.new(context, reader, {})
|
|
197
|
+
table.insert(_potentials, _parseResults)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
if potentials ~= nil then
|
|
201
|
+
if #potentials > 1 then
|
|
202
|
+
stableSort(potentials, compareParses)
|
|
203
|
+
end
|
|
204
|
+
return potentials[1]
|
|
205
|
+
end
|
|
206
|
+
return ParseResults.new(contextSoFar, originalReader, errors or {})
|
|
207
|
+
end
|
|
208
|
+
function CommandDispatcher:getAllUsage(node, source, restricted)
|
|
209
|
+
local result = {}
|
|
210
|
+
self:getAllUsageRecursive(node, source, result, "", restricted)
|
|
211
|
+
return result
|
|
212
|
+
end
|
|
213
|
+
function CommandDispatcher:getAllUsageRecursive(node, source, result, prefix, restricted)
|
|
214
|
+
if restricted and not node:canUse(source) then
|
|
215
|
+
return nil
|
|
216
|
+
end
|
|
217
|
+
if node:getCommand() ~= nil then
|
|
218
|
+
local _result = result
|
|
219
|
+
local _prefix = prefix
|
|
220
|
+
table.insert(_result, _prefix)
|
|
221
|
+
end
|
|
222
|
+
local redirect = node:getRedirect()
|
|
223
|
+
if redirect ~= nil then
|
|
224
|
+
local redirectText = if rawequal(redirect, self.root) then "..." else "-> " .. redirect:getUsageText()
|
|
225
|
+
local _result = result
|
|
226
|
+
local _arg0 = if prefix == "" then node:getUsageText() .. ARGUMENT_SEPARATOR .. redirectText else prefix .. ARGUMENT_SEPARATOR .. redirectText
|
|
227
|
+
table.insert(_result, _arg0)
|
|
228
|
+
else
|
|
229
|
+
for _, child in node:getChildren() do
|
|
230
|
+
self:getAllUsageRecursive(child, source, result, if prefix == "" then child:getUsageText() else prefix .. ARGUMENT_SEPARATOR .. child:getUsageText(), restricted)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
function CommandDispatcher:getSmartUsage(node, source)
|
|
235
|
+
local result = {}
|
|
236
|
+
local optional = node:getCommand() ~= nil
|
|
237
|
+
for _, child in node:getChildren() do
|
|
238
|
+
local usage = self:getSmartUsageRecursive(child, source, optional, false)
|
|
239
|
+
if usage ~= nil then
|
|
240
|
+
result[child] = usage
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
return result
|
|
244
|
+
end
|
|
245
|
+
function CommandDispatcher:getSmartUsageRecursive(node, source, optional, deep)
|
|
246
|
+
if not node:canUse(source) then
|
|
247
|
+
return nil
|
|
248
|
+
end
|
|
249
|
+
local selfUsage = if optional then USAGE_OPTIONAL_OPEN .. node:getUsageText() .. USAGE_OPTIONAL_CLOSE else node:getUsageText()
|
|
250
|
+
local childOptional = node:getCommand() ~= nil
|
|
251
|
+
local open = if childOptional then USAGE_OPTIONAL_OPEN else USAGE_REQUIRED_OPEN
|
|
252
|
+
local close = if childOptional then USAGE_OPTIONAL_CLOSE else USAGE_REQUIRED_CLOSE
|
|
253
|
+
if not deep then
|
|
254
|
+
local redirect = node:getRedirect()
|
|
255
|
+
if redirect ~= nil then
|
|
256
|
+
local redirectText = if rawequal(redirect, self.root) then "..." else "-> " .. redirect:getUsageText()
|
|
257
|
+
return selfUsage .. ARGUMENT_SEPARATOR .. redirectText
|
|
258
|
+
end
|
|
259
|
+
local _exp = node:getChildren()
|
|
260
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
261
|
+
local _newValue = {}
|
|
262
|
+
local _callback = function(child)
|
|
263
|
+
return child:canUse(source)
|
|
264
|
+
end
|
|
265
|
+
local _length = 0
|
|
266
|
+
for _k, _v in _exp do
|
|
267
|
+
if _callback(_v, _k - 1, _exp) == true then
|
|
268
|
+
_length += 1
|
|
269
|
+
_newValue[_length] = _v
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
273
|
+
local children = _newValue
|
|
274
|
+
if #children == 1 then
|
|
275
|
+
local usage = self:getSmartUsageRecursive(children[1], source, childOptional, childOptional)
|
|
276
|
+
if usage ~= nil then
|
|
277
|
+
return selfUsage .. ARGUMENT_SEPARATOR .. usage
|
|
278
|
+
end
|
|
279
|
+
elseif #children > 1 then
|
|
280
|
+
-- A LinkedHashSet<String>.
|
|
281
|
+
local childUsage = {}
|
|
282
|
+
for _, child in children do
|
|
283
|
+
local usage = self:getSmartUsageRecursive(child, source, childOptional, true)
|
|
284
|
+
if usage ~= nil and not (table.find(childUsage, usage) ~= nil) then
|
|
285
|
+
table.insert(childUsage, usage)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
if #childUsage == 1 then
|
|
289
|
+
local usage = childUsage[1]
|
|
290
|
+
return selfUsage .. ARGUMENT_SEPARATOR .. (if childOptional then USAGE_OPTIONAL_OPEN .. usage .. USAGE_OPTIONAL_CLOSE else usage)
|
|
291
|
+
elseif #childUsage > 1 then
|
|
292
|
+
local builder = open
|
|
293
|
+
local count = 0
|
|
294
|
+
for _, child in children do
|
|
295
|
+
if count > 0 then
|
|
296
|
+
builder ..= USAGE_OR
|
|
297
|
+
end
|
|
298
|
+
builder ..= child:getUsageText()
|
|
299
|
+
count += 1
|
|
300
|
+
end
|
|
301
|
+
if count > 0 then
|
|
302
|
+
builder ..= close
|
|
303
|
+
return selfUsage .. ARGUMENT_SEPARATOR .. builder
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
return selfUsage
|
|
309
|
+
end
|
|
310
|
+
function CommandDispatcher:getCompletionSuggestions(parse, cursor)
|
|
311
|
+
local _condition = cursor
|
|
312
|
+
if _condition == nil then
|
|
313
|
+
_condition = parse:getReader():getTotalLength()
|
|
314
|
+
end
|
|
315
|
+
local cursorPosition = _condition
|
|
316
|
+
local context = parse:getContext()
|
|
317
|
+
local nodeBeforeCursor = context:findSuggestionContext(cursorPosition)
|
|
318
|
+
local parent = nodeBeforeCursor.parent
|
|
319
|
+
local start = math.min(nodeBeforeCursor.startPos, cursorPosition)
|
|
320
|
+
local fullInput = parse:getReader():getString()
|
|
321
|
+
local truncatedInput = substring(fullInput, 0, cursorPosition)
|
|
322
|
+
local truncatedInputLowerCase = toLowerCase(truncatedInput)
|
|
323
|
+
local futures = {}
|
|
324
|
+
for _, node in parent:getChildren() do
|
|
325
|
+
local future = Suggestions:empty()
|
|
326
|
+
TS.try(function()
|
|
327
|
+
future = node:listSuggestions(nodeBeforeCursor.context:build(truncatedInput), SuggestionsBuilder.new(truncatedInput, truncatedInputLowerCase, start))
|
|
328
|
+
end, function(err)
|
|
329
|
+
if not (TS.instanceof(err, CommandSyntaxException)) then
|
|
330
|
+
rethrow(err)
|
|
331
|
+
end
|
|
332
|
+
end)
|
|
333
|
+
local _future = future
|
|
334
|
+
table.insert(futures, _future)
|
|
335
|
+
end
|
|
336
|
+
-- Promise.all's typings lose the element type of an array that isn't a tuple.
|
|
337
|
+
return TS.Promise.all(futures):andThen(function(suggestions)
|
|
338
|
+
return Suggestions:merge(fullInput, suggestions)
|
|
339
|
+
end)
|
|
340
|
+
end
|
|
341
|
+
function CommandDispatcher:getRoot()
|
|
342
|
+
return self.root
|
|
343
|
+
end
|
|
344
|
+
function CommandDispatcher:getPath(target)
|
|
345
|
+
local nodes = {}
|
|
346
|
+
local addPaths
|
|
347
|
+
addPaths = function(node, parents)
|
|
348
|
+
local _array = {}
|
|
349
|
+
local _length = #_array
|
|
350
|
+
local _parentsLength = #parents
|
|
351
|
+
table.move(parents, 1, _parentsLength, _length + 1, _array)
|
|
352
|
+
_length += _parentsLength
|
|
353
|
+
_array[_length + 1] = node
|
|
354
|
+
local current = _array
|
|
355
|
+
table.insert(nodes, current)
|
|
356
|
+
for _, child in node:getChildren() do
|
|
357
|
+
addPaths(child, current)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
addPaths(self.root, {})
|
|
361
|
+
for _, list in nodes do
|
|
362
|
+
if rawequal(list[#list], target) then
|
|
363
|
+
local result = {}
|
|
364
|
+
for _1, node in list do
|
|
365
|
+
if not rawequal(node, self.root) then
|
|
366
|
+
local _arg0 = node:getName()
|
|
367
|
+
table.insert(result, _arg0)
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
return result
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
return {}
|
|
374
|
+
end
|
|
375
|
+
function CommandDispatcher:findNode(path)
|
|
376
|
+
local node = self.root
|
|
377
|
+
for _, name in path do
|
|
378
|
+
node = node:getChild(name)
|
|
379
|
+
if node == nil then
|
|
380
|
+
return nil
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
return node
|
|
384
|
+
end
|
|
385
|
+
function CommandDispatcher:findAmbiguities(consumer)
|
|
386
|
+
self.root:findAmbiguities(consumer)
|
|
387
|
+
end
|
|
388
|
+
CommandDispatcher.ARGUMENT_SEPARATOR = ARGUMENT_SEPARATOR
|
|
389
|
+
CommandDispatcher.ARGUMENT_SEPARATOR_CHAR = ARGUMENT_SEPARATOR
|
|
390
|
+
end
|
|
391
|
+
return {
|
|
392
|
+
ParseResults = ParseResults,
|
|
393
|
+
CommandDispatcher = CommandDispatcher,
|
|
394
|
+
}
|
package/out/command.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CommandContext } from "./context";
|
|
2
|
+
import type { Suggestions, SuggestionsBuilder } from "./suggestion";
|
|
3
|
+
import type { CommandNode } from "./tree";
|
|
4
|
+
export type Command<S> = (context: CommandContext<S>) => number;
|
|
5
|
+
export declare const Command: {
|
|
6
|
+
readonly SINGLE_SUCCESS: 1;
|
|
7
|
+
};
|
|
8
|
+
export type Predicate<S> = (source: S) => boolean;
|
|
9
|
+
export type RedirectModifier<S> = (context: CommandContext<S>) => readonly S[];
|
|
10
|
+
export type SingleRedirectModifier<S> = (context: CommandContext<S>) => S;
|
|
11
|
+
export type ResultConsumer<S> = (context: CommandContext<S>, success: boolean, result: number) => void;
|
|
12
|
+
export type AmbiguityConsumer<S> = (parent: CommandNode<S>, child: CommandNode<S>, sibling: CommandNode<S>, inputs: readonly string[]) => void;
|
|
13
|
+
export type SuggestionProvider<S> = (context: CommandContext<S>, builder: SuggestionsBuilder) => Promise<Suggestions>;
|
package/out/command.luau
ADDED
package/out/context.d.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Command, RedirectModifier, ResultConsumer } from "./command";
|
|
2
|
+
import type { CommandDispatcher } from "./command-dispatcher";
|
|
3
|
+
import type { ImmutableStringReader } from "./string-reader";
|
|
4
|
+
import type { CommandNode } from "./tree";
|
|
5
|
+
export declare class StringRange {
|
|
6
|
+
private readonly start;
|
|
7
|
+
private readonly finish;
|
|
8
|
+
constructor(start: number, finish: number);
|
|
9
|
+
static at(pos: number): StringRange;
|
|
10
|
+
static between(start: number, finish: number): StringRange;
|
|
11
|
+
static encompassing(a: StringRange, b: StringRange): StringRange;
|
|
12
|
+
getStart(): number;
|
|
13
|
+
getEnd(): number;
|
|
14
|
+
get(reader: ImmutableStringReader | string): string;
|
|
15
|
+
isEmpty(): boolean;
|
|
16
|
+
getLength(): number;
|
|
17
|
+
equals(other: unknown): boolean;
|
|
18
|
+
toString(): string;
|
|
19
|
+
}
|
|
20
|
+
export declare class ParsedArgument<T> {
|
|
21
|
+
private readonly result;
|
|
22
|
+
private readonly range;
|
|
23
|
+
constructor(start: number, finish: number, result: T);
|
|
24
|
+
getRange(): StringRange;
|
|
25
|
+
getResult(): T;
|
|
26
|
+
equals(other: unknown): boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare class ParsedCommandNode<S> {
|
|
29
|
+
private readonly node;
|
|
30
|
+
private readonly range;
|
|
31
|
+
constructor(node: CommandNode<S>, range: StringRange);
|
|
32
|
+
getNode(): CommandNode<S>;
|
|
33
|
+
getRange(): StringRange;
|
|
34
|
+
toString(): string;
|
|
35
|
+
equals(other: unknown): boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare class SuggestionContext<S> {
|
|
38
|
+
readonly context: CommandContextBuilder<S>;
|
|
39
|
+
readonly parent: CommandNode<S>;
|
|
40
|
+
readonly startPos: number;
|
|
41
|
+
constructor(context: CommandContextBuilder<S>, parent: CommandNode<S>, startPos: number);
|
|
42
|
+
}
|
|
43
|
+
interface Checkable {
|
|
44
|
+
any: unknown;
|
|
45
|
+
}
|
|
46
|
+
export type ArgumentClass = keyof CheckableTypes | keyof Checkable | (new (...args: never[]) => object);
|
|
47
|
+
export declare class CommandContext<S> {
|
|
48
|
+
private readonly source;
|
|
49
|
+
private readonly input;
|
|
50
|
+
private readonly args;
|
|
51
|
+
private readonly command;
|
|
52
|
+
private readonly rootNode;
|
|
53
|
+
private readonly nodes;
|
|
54
|
+
private readonly range;
|
|
55
|
+
private readonly child;
|
|
56
|
+
private readonly modifier;
|
|
57
|
+
private readonly forks;
|
|
58
|
+
constructor(source: S, input: string, args: ReadonlyMap<string, ParsedArgument<unknown>>, command: Command<S> | undefined, rootNode: CommandNode<S>, nodes: readonly ParsedCommandNode<S>[], range: StringRange, child: CommandContext<S> | undefined, modifier: RedirectModifier<S> | undefined, forks: boolean);
|
|
59
|
+
copyFor(source: S): CommandContext<S>;
|
|
60
|
+
getChild(): CommandContext<S> | undefined;
|
|
61
|
+
getLastChild(): CommandContext<S>;
|
|
62
|
+
getCommand(): Command<S> | undefined;
|
|
63
|
+
getSource(): S;
|
|
64
|
+
getArgument<V>(name: string, clazz: ArgumentClass): V;
|
|
65
|
+
equals(other: unknown): boolean;
|
|
66
|
+
getRedirectModifier(): RedirectModifier<S> | undefined;
|
|
67
|
+
getRange(): StringRange;
|
|
68
|
+
getInput(): string;
|
|
69
|
+
getRootNode(): CommandNode<S>;
|
|
70
|
+
getNodes(): readonly ParsedCommandNode<S>[];
|
|
71
|
+
hasNodes(): boolean;
|
|
72
|
+
isForked(): boolean;
|
|
73
|
+
}
|
|
74
|
+
export declare class CommandContextBuilder<S> {
|
|
75
|
+
private readonly dispatcher;
|
|
76
|
+
private source;
|
|
77
|
+
private readonly rootNode;
|
|
78
|
+
private readonly args;
|
|
79
|
+
private readonly nodes;
|
|
80
|
+
private command?;
|
|
81
|
+
private child?;
|
|
82
|
+
private range;
|
|
83
|
+
private modifier?;
|
|
84
|
+
private forks;
|
|
85
|
+
constructor(dispatcher: CommandDispatcher<S>, source: S, rootNode: CommandNode<S>, start: number);
|
|
86
|
+
withSource(source: S): this;
|
|
87
|
+
getSource(): S;
|
|
88
|
+
getRootNode(): CommandNode<S>;
|
|
89
|
+
withArgument(name: string, argument: ParsedArgument<unknown>): this;
|
|
90
|
+
getArguments(): ReadonlyMap<string, ParsedArgument<unknown>>;
|
|
91
|
+
withCommand(command: Command<S> | undefined): this;
|
|
92
|
+
withNode(node: CommandNode<S>, range: StringRange): this;
|
|
93
|
+
copy(): CommandContextBuilder<S>;
|
|
94
|
+
withChild(child: CommandContextBuilder<S>): this;
|
|
95
|
+
getChild(): CommandContextBuilder<S> | undefined;
|
|
96
|
+
getLastChild(): CommandContextBuilder<S>;
|
|
97
|
+
getCommand(): Command<S> | undefined;
|
|
98
|
+
getNodes(): readonly ParsedCommandNode<S>[];
|
|
99
|
+
build(input: string): CommandContext<S>;
|
|
100
|
+
getDispatcher(): CommandDispatcher<S>;
|
|
101
|
+
getRange(): StringRange;
|
|
102
|
+
findSuggestionContext(cursor: number): SuggestionContext<S>;
|
|
103
|
+
}
|
|
104
|
+
export declare class ContextChain<S> {
|
|
105
|
+
private readonly modifiers;
|
|
106
|
+
private readonly executable;
|
|
107
|
+
static readonly Stage: {
|
|
108
|
+
readonly MODIFY: "MODIFY";
|
|
109
|
+
readonly EXECUTE: "EXECUTE";
|
|
110
|
+
};
|
|
111
|
+
private nextStageCache?;
|
|
112
|
+
constructor(modifiers: readonly CommandContext<S>[], executable: CommandContext<S>);
|
|
113
|
+
static tryFlatten<S>(rootContext: CommandContext<S>): ContextChain<S> | undefined;
|
|
114
|
+
static runModifier<S>(modifier: CommandContext<S>, source: S, resultConsumer: ResultConsumer<S>, forkedMode: boolean): readonly S[];
|
|
115
|
+
static runExecutable<S>(executable: CommandContext<S>, source: S, resultConsumer: ResultConsumer<S>, forkedMode: boolean): number;
|
|
116
|
+
executeAll(source: S, resultConsumer: ResultConsumer<S>): number;
|
|
117
|
+
getStage(): (typeof ContextChain.Stage)[keyof typeof ContextChain.Stage];
|
|
118
|
+
getTopContext(): CommandContext<S>;
|
|
119
|
+
nextStage(): ContextChain<S> | undefined;
|
|
120
|
+
}
|
|
121
|
+
export {};
|