@rbxts/centurion-ui 1.0.0-dev-47fa67f → 1.0.0-dev-84057f1
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/out/components/suggestions/suggestion-list.lua +16 -11
- package/out/components/terminal/command.d.ts +5 -0
- package/out/components/terminal/command.lua +71 -0
- package/out/components/terminal/suggestion.d.ts +26 -0
- package/out/components/terminal/suggestion.lua +187 -0
- package/out/components/terminal/terminal-text-field.lua +67 -42
- package/out/components/terminal/terminal.lua +119 -89
- package/out/store.d.ts +3 -2
- package/out/store.lua +6 -13
- package/package.json +4 -4
- package/out/util/argument.d.ts +0 -3
- package/out/util/argument.lua +0 -51
- package/out/util/suggestion.d.ts +0 -4
- package/out/util/suggestion.lua +0 -203
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
2
|
local TS = _G[script]
|
|
3
|
+
local ArrayUtil = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.data).ArrayUtil
|
|
3
4
|
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
4
5
|
local Vide = _vide
|
|
6
|
+
local derive = _vide.derive
|
|
5
7
|
local For = _vide.For
|
|
6
8
|
local read = _vide.read
|
|
7
9
|
local SUGGESTION_TEXT_SIZE = TS.import(script, script.Parent.Parent.Parent, "constants", "text").SUGGESTION_TEXT_SIZE
|
|
@@ -15,11 +17,23 @@ local Group = TS.import(script, script.Parent.Parent, "ui", "group").Group
|
|
|
15
17
|
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
16
18
|
local Text = TS.import(script, script.Parent.Parent, "ui", "text").Text
|
|
17
19
|
local highlightMatching = TS.import(script, script.Parent, "util").highlightMatching
|
|
20
|
+
local MAX_SUGGESTIONS = 3
|
|
18
21
|
local function SuggestionList(_param)
|
|
19
22
|
local suggestion = _param.suggestion
|
|
20
23
|
local currentText = _param.currentText
|
|
21
24
|
local size = _param.size
|
|
22
25
|
local options = useAtom(interfaceOptions)
|
|
26
|
+
local suggestions = derive(function()
|
|
27
|
+
local _result = read(suggestion)
|
|
28
|
+
if _result ~= nil then
|
|
29
|
+
_result = _result.others
|
|
30
|
+
end
|
|
31
|
+
local _condition = _result
|
|
32
|
+
if _condition == nil then
|
|
33
|
+
_condition = {}
|
|
34
|
+
end
|
|
35
|
+
return ArrayUtil.slice(_condition, 0, MAX_SUGGESTIONS)
|
|
36
|
+
end)
|
|
23
37
|
return Vide.jsx(Group, {
|
|
24
38
|
size = size,
|
|
25
39
|
mouseEnter = function()
|
|
@@ -34,17 +48,7 @@ local function SuggestionList(_param)
|
|
|
34
48
|
return UDim.new(0, px(8))
|
|
35
49
|
end,
|
|
36
50
|
}), Vide.jsx(For, {
|
|
37
|
-
each =
|
|
38
|
-
local _result = read(suggestion)
|
|
39
|
-
if _result ~= nil then
|
|
40
|
-
_result = _result.others
|
|
41
|
-
end
|
|
42
|
-
local _condition = _result
|
|
43
|
-
if _condition == nil then
|
|
44
|
-
_condition = {}
|
|
45
|
-
end
|
|
46
|
-
return _condition
|
|
47
|
-
end,
|
|
51
|
+
each = suggestions,
|
|
48
52
|
}, function(name, i)
|
|
49
53
|
return Vide.jsx(Frame, {
|
|
50
54
|
size = function()
|
|
@@ -64,6 +68,7 @@ local function SuggestionList(_param)
|
|
|
64
68
|
return UDim.new(0, px(8))
|
|
65
69
|
end,
|
|
66
70
|
clipsDescendants = true,
|
|
71
|
+
layoutOrder = i,
|
|
67
72
|
}, Vide.jsx(Padding, {
|
|
68
73
|
all = function()
|
|
69
74
|
return UDim.new(0, px(4))
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseRegistry, ImmutableRegistryPath, RegistryPath } from "@rbxts/centurion";
|
|
2
|
+
import { BaseCommand } from "@rbxts/centurion/out/shared/core/command";
|
|
3
|
+
export declare function getValidPath(registry: BaseRegistry, text: string[]): ImmutableRegistryPath | undefined;
|
|
4
|
+
export declare function getArgumentNames(registry: BaseRegistry, path: RegistryPath): string[];
|
|
5
|
+
export declare function getMissingArgs(command: BaseCommand, text: string[]): string[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _centurion = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out)
|
|
4
|
+
local ImmutableRegistryPath = _centurion.ImmutableRegistryPath
|
|
5
|
+
local RegistryPath = _centurion.RegistryPath
|
|
6
|
+
local formatPartsAsPath = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.string).formatPartsAsPath
|
|
7
|
+
local IS_EDIT = TS.import(script, script.Parent.Parent.Parent, "constants", "util").IS_EDIT
|
|
8
|
+
local function getValidPath(registry, text)
|
|
9
|
+
if #text == 0 then
|
|
10
|
+
return nil
|
|
11
|
+
end
|
|
12
|
+
local textPath = formatPartsAsPath(text)
|
|
13
|
+
if registry:getCommandByString(textPath) ~= nil or registry:getGroupByString(textPath) ~= nil then
|
|
14
|
+
return ImmutableRegistryPath:fromString(textPath)
|
|
15
|
+
end
|
|
16
|
+
local path = RegistryPath:empty()
|
|
17
|
+
for _, part in text do
|
|
18
|
+
path:append(part)
|
|
19
|
+
if registry:getCommand(path) == nil and registry:getGroup(path) == nil and #registry:getChildPaths(path) == 0 then
|
|
20
|
+
path:remove(path:size() - 1)
|
|
21
|
+
break
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
if registry:getCommand(path) ~= nil or registry:getGroup(path) ~= nil then
|
|
25
|
+
return ImmutableRegistryPath:fromPath(path)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
local function getArgumentNames(registry, path)
|
|
29
|
+
if IS_EDIT then
|
|
30
|
+
return {}
|
|
31
|
+
end
|
|
32
|
+
local command = registry:getCommand(path)
|
|
33
|
+
if command == nil or command.options.arguments == nil then
|
|
34
|
+
return {}
|
|
35
|
+
end
|
|
36
|
+
local _exp = command.options.arguments
|
|
37
|
+
-- ▼ ReadonlyArray.map ▼
|
|
38
|
+
local _newValue = table.create(#_exp)
|
|
39
|
+
local _callback = function(arg)
|
|
40
|
+
return arg.name
|
|
41
|
+
end
|
|
42
|
+
for _k, _v in _exp do
|
|
43
|
+
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
44
|
+
end
|
|
45
|
+
-- ▲ ReadonlyArray.map ▲
|
|
46
|
+
return _newValue
|
|
47
|
+
end
|
|
48
|
+
local function getMissingArgs(command, text)
|
|
49
|
+
if command.options.arguments == nil or #command.options.arguments == 0 then
|
|
50
|
+
return {}
|
|
51
|
+
end
|
|
52
|
+
local lastPartIndex = #text - command:getPath():size() - 1
|
|
53
|
+
local missingArgs = {}
|
|
54
|
+
local index = 0
|
|
55
|
+
for _, arg in command.options.arguments do
|
|
56
|
+
if arg.optional then
|
|
57
|
+
break
|
|
58
|
+
end
|
|
59
|
+
if index > lastPartIndex then
|
|
60
|
+
local _name = arg.name
|
|
61
|
+
table.insert(missingArgs, _name)
|
|
62
|
+
end
|
|
63
|
+
index += 1
|
|
64
|
+
end
|
|
65
|
+
return missingArgs
|
|
66
|
+
end
|
|
67
|
+
return {
|
|
68
|
+
getValidPath = getValidPath,
|
|
69
|
+
getArgumentNames = getArgumentNames,
|
|
70
|
+
getMissingArgs = getMissingArgs,
|
|
71
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ArgumentOptions, BaseRegistry, ListArgumentType, RegistryPath, SingleArgumentType } from "@rbxts/centurion";
|
|
2
|
+
import { ReadonlyDeep } from "@rbxts/centurion/out/shared/util/data";
|
|
3
|
+
import { CommandSuggestion } from "../../types";
|
|
4
|
+
export interface SingleArgument {
|
|
5
|
+
kind: "single";
|
|
6
|
+
options: ReadonlyDeep<ArgumentOptions>;
|
|
7
|
+
type: SingleArgumentType<unknown>;
|
|
8
|
+
input?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ListArgument {
|
|
11
|
+
kind: "list";
|
|
12
|
+
options: ReadonlyDeep<ArgumentOptions>;
|
|
13
|
+
type: ListArgumentType<unknown>;
|
|
14
|
+
input: string[];
|
|
15
|
+
}
|
|
16
|
+
export type Argument = SingleArgument | ListArgument;
|
|
17
|
+
export declare function getArgumentSuggestion(arg: Argument, textPart?: string): {
|
|
18
|
+
type: "argument";
|
|
19
|
+
title: string;
|
|
20
|
+
others: string[];
|
|
21
|
+
description: string;
|
|
22
|
+
dataType: string;
|
|
23
|
+
optional: boolean;
|
|
24
|
+
error: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
export declare function getCommandSuggestion(registry: BaseRegistry, parentPath?: RegistryPath, text?: string): CommandSuggestion | undefined;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local Players = TS.import(script, TS.getModule(script, "@rbxts", "services")).Players
|
|
4
|
+
local MAX_OTHER_SUGGESTIONS = 3
|
|
5
|
+
local function getMatches(strings, text)
|
|
6
|
+
if text == nil then
|
|
7
|
+
table.sort(strings)
|
|
8
|
+
-- ▼ ReadonlyArray.map ▼
|
|
9
|
+
local _newValue = table.create(#strings)
|
|
10
|
+
local _callback = function(str, i)
|
|
11
|
+
return { i, str, #str }
|
|
12
|
+
end
|
|
13
|
+
for _k, _v in strings do
|
|
14
|
+
_newValue[_k] = _callback(_v, _k - 1, strings)
|
|
15
|
+
end
|
|
16
|
+
-- ▲ ReadonlyArray.map ▲
|
|
17
|
+
return _newValue
|
|
18
|
+
end
|
|
19
|
+
local textLower = string.lower(text)
|
|
20
|
+
local textEndIndex = #text
|
|
21
|
+
-- ▼ ReadonlyArray.mapFiltered ▼
|
|
22
|
+
local _newValue = {}
|
|
23
|
+
local _callback = function(str, i)
|
|
24
|
+
local part = string.sub(string.lower(str), 0, textEndIndex)
|
|
25
|
+
if part == textLower then
|
|
26
|
+
return { i, str, #str }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
local _length = 0
|
|
30
|
+
for _k, _v in strings do
|
|
31
|
+
local _result = _callback(_v, _k - 1, strings)
|
|
32
|
+
if _result ~= nil then
|
|
33
|
+
_length += 1
|
|
34
|
+
_newValue[_length] = _result
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
-- ▲ ReadonlyArray.mapFiltered ▲
|
|
38
|
+
table.sort(_newValue, function(a, b)
|
|
39
|
+
return a[2] < b[2]
|
|
40
|
+
end)
|
|
41
|
+
return _newValue
|
|
42
|
+
end
|
|
43
|
+
local function getArgumentSuggestion(arg, textPart)
|
|
44
|
+
local _array = {}
|
|
45
|
+
local _length = #_array
|
|
46
|
+
local _array_1 = (arg.options.suggestions or {})
|
|
47
|
+
table.move(_array_1, 1, #_array_1, _length + 1, _array)
|
|
48
|
+
local suggestions = _array
|
|
49
|
+
local singleArg = arg.kind == "single"
|
|
50
|
+
local _result
|
|
51
|
+
if singleArg then
|
|
52
|
+
local _result_1 = arg.type.suggestions
|
|
53
|
+
if _result_1 ~= nil then
|
|
54
|
+
local _condition = arg.input
|
|
55
|
+
if _condition == nil then
|
|
56
|
+
_condition = ""
|
|
57
|
+
end
|
|
58
|
+
_result_1 = _result_1(_condition, Players.LocalPlayer)
|
|
59
|
+
end
|
|
60
|
+
_result = _result_1
|
|
61
|
+
else
|
|
62
|
+
local _result_1 = arg.type.suggestions
|
|
63
|
+
if _result_1 ~= nil then
|
|
64
|
+
_result_1 = _result_1(arg.input, Players.LocalPlayer)
|
|
65
|
+
end
|
|
66
|
+
_result = _result_1
|
|
67
|
+
end
|
|
68
|
+
local typeSuggestions = _result
|
|
69
|
+
if typeSuggestions ~= nil then
|
|
70
|
+
for _, text in typeSuggestions do
|
|
71
|
+
table.insert(suggestions, text)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
local errorText
|
|
75
|
+
if not arg.type.expensive then
|
|
76
|
+
local success, err = pcall(function()
|
|
77
|
+
local _result_1
|
|
78
|
+
if singleArg then
|
|
79
|
+
local _type = arg.type
|
|
80
|
+
local _condition = arg.input
|
|
81
|
+
if _condition == nil then
|
|
82
|
+
_condition = ""
|
|
83
|
+
end
|
|
84
|
+
_result_1 = _type.transform(_condition, Players.LocalPlayer)
|
|
85
|
+
else
|
|
86
|
+
_result_1 = arg.type.transform(arg.input, Players.LocalPlayer)
|
|
87
|
+
end
|
|
88
|
+
local transformResult = _result_1
|
|
89
|
+
if transformResult.ok then
|
|
90
|
+
return nil
|
|
91
|
+
end
|
|
92
|
+
errorText = transformResult.value
|
|
93
|
+
end)
|
|
94
|
+
if not success then
|
|
95
|
+
errorText = "Failed to transform argument"
|
|
96
|
+
warn(err)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
local _object = {
|
|
100
|
+
type = "argument",
|
|
101
|
+
title = arg.options.name,
|
|
102
|
+
}
|
|
103
|
+
local _left = "others"
|
|
104
|
+
local _exp = getMatches(suggestions, textPart)
|
|
105
|
+
-- ▼ ReadonlyArray.map ▼
|
|
106
|
+
local _newValue = table.create(#_exp)
|
|
107
|
+
local _callback = function(_param)
|
|
108
|
+
local str = _param[2]
|
|
109
|
+
return str
|
|
110
|
+
end
|
|
111
|
+
for _k, _v in _exp do
|
|
112
|
+
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
113
|
+
end
|
|
114
|
+
-- ▲ ReadonlyArray.map ▲
|
|
115
|
+
_object[_left] = _newValue
|
|
116
|
+
_object.description = arg.options.description
|
|
117
|
+
_object.dataType = arg.type.name
|
|
118
|
+
local _left_1 = "optional"
|
|
119
|
+
local _condition = arg.options.optional
|
|
120
|
+
if _condition == nil then
|
|
121
|
+
_condition = false
|
|
122
|
+
end
|
|
123
|
+
_object[_left_1] = _condition
|
|
124
|
+
_object.error = errorText
|
|
125
|
+
return _object
|
|
126
|
+
end
|
|
127
|
+
local function getCommandSuggestion(registry, parentPath, text)
|
|
128
|
+
local paths = if parentPath ~= nil then registry:getChildPaths(parentPath) else registry:getRootPaths()
|
|
129
|
+
if #paths == 0 then
|
|
130
|
+
return nil
|
|
131
|
+
end
|
|
132
|
+
-- ▼ ReadonlyArray.map ▼
|
|
133
|
+
local _newValue = table.create(#paths)
|
|
134
|
+
local _callback = function(path)
|
|
135
|
+
return path:tail()
|
|
136
|
+
end
|
|
137
|
+
for _k, _v in paths do
|
|
138
|
+
_newValue[_k] = _callback(_v, _k - 1, paths)
|
|
139
|
+
end
|
|
140
|
+
-- ▲ ReadonlyArray.map ▲
|
|
141
|
+
local pathNames = _newValue
|
|
142
|
+
local sortedPaths = getMatches(pathNames, text)
|
|
143
|
+
local firstMatch = table.remove(sortedPaths, 1)
|
|
144
|
+
if firstMatch == nil then
|
|
145
|
+
return nil
|
|
146
|
+
end
|
|
147
|
+
local firstPath = paths[firstMatch[1] + 1]
|
|
148
|
+
local _result = registry:getCommand(firstPath)
|
|
149
|
+
if _result ~= nil then
|
|
150
|
+
_result = _result.options
|
|
151
|
+
end
|
|
152
|
+
local _condition = _result
|
|
153
|
+
if _condition == nil then
|
|
154
|
+
local _result_1 = registry:getGroup(firstPath)
|
|
155
|
+
if _result_1 ~= nil then
|
|
156
|
+
_result_1 = _result_1.options
|
|
157
|
+
end
|
|
158
|
+
_condition = _result_1
|
|
159
|
+
end
|
|
160
|
+
local mainData = _condition
|
|
161
|
+
if mainData == nil then
|
|
162
|
+
return nil
|
|
163
|
+
end
|
|
164
|
+
local _object = {
|
|
165
|
+
type = "command",
|
|
166
|
+
title = firstPath:tail(),
|
|
167
|
+
}
|
|
168
|
+
local _left = "others"
|
|
169
|
+
-- ▼ ReadonlyArray.map ▼
|
|
170
|
+
local _newValue_1 = table.create(#sortedPaths)
|
|
171
|
+
local _callback_1 = function(_param)
|
|
172
|
+
local str = _param[2]
|
|
173
|
+
return str
|
|
174
|
+
end
|
|
175
|
+
for _k, _v in sortedPaths do
|
|
176
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, sortedPaths)
|
|
177
|
+
end
|
|
178
|
+
-- ▲ ReadonlyArray.map ▲
|
|
179
|
+
_object[_left] = _newValue_1
|
|
180
|
+
_object.description = mainData.description
|
|
181
|
+
_object.shortcuts = mainData.shortcuts
|
|
182
|
+
return _object
|
|
183
|
+
end
|
|
184
|
+
return {
|
|
185
|
+
getArgumentSuggestion = getArgumentSuggestion,
|
|
186
|
+
getCommandSuggestion = getCommandSuggestion,
|
|
187
|
+
}
|
|
@@ -15,19 +15,21 @@ local useAtom = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-ato
|
|
|
15
15
|
local useEvent = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-event").useEvent
|
|
16
16
|
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
17
17
|
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
18
|
-
local
|
|
18
|
+
local commandArgIndex = _store.commandArgIndex
|
|
19
19
|
local currentCommandPath = _store.currentCommandPath
|
|
20
20
|
local currentSuggestion = _store.currentSuggestion
|
|
21
|
+
local currentTextPart = _store.currentTextPart
|
|
21
22
|
local interfaceOptions = _store.interfaceOptions
|
|
22
23
|
local interfaceVisible = _store.interfaceVisible
|
|
24
|
+
local terminalArgIndex = _store.terminalArgIndex
|
|
23
25
|
local terminalText = _store.terminalText
|
|
24
26
|
local terminalTextParts = _store.terminalTextParts
|
|
25
27
|
local terminalTextValid = _store.terminalTextValid
|
|
26
|
-
local getArgumentNames = TS.import(script, script.Parent.Parent.Parent, "util", "argument").getArgumentNames
|
|
27
28
|
local Frame = TS.import(script, script.Parent.Parent, "ui", "frame").Frame
|
|
28
29
|
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
29
30
|
local Text = TS.import(script, script.Parent.Parent, "ui", "text").Text
|
|
30
31
|
local TextField = TS.import(script, script.Parent.Parent, "ui", "text-field").TextField
|
|
32
|
+
local getArgumentNames = TS.import(script, script.Parent, "command").getArgumentNames
|
|
31
33
|
local TEXT_SIZE = 22
|
|
32
34
|
local function TerminalTextField(_param)
|
|
33
35
|
local anchorPoint = _param.anchorPoint
|
|
@@ -96,27 +98,40 @@ local function TerminalTextField(_param)
|
|
|
96
98
|
end
|
|
97
99
|
local atNextPart = endsWithSpace(terminalText())
|
|
98
100
|
local textParts = terminalTextParts()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
if #textParts == 0 then
|
|
102
|
+
suggestionText(suggestion.title)
|
|
103
|
+
return nil
|
|
104
|
+
end
|
|
105
|
+
-- Command suggestions
|
|
106
|
+
if suggestion.type == "command" then
|
|
107
|
+
local suggestionStartIndex = (if not atNextPart then #textParts[#textParts] else 0) + 1
|
|
101
108
|
suggestionText(text() .. string.sub(suggestion.title, suggestionStartIndex))
|
|
102
109
|
return nil
|
|
103
110
|
end
|
|
111
|
+
-- Argument suggestions
|
|
104
112
|
local command = currentCommandPath()
|
|
105
|
-
local argIndex =
|
|
113
|
+
local argIndex = terminalArgIndex()
|
|
106
114
|
if suggestion.type ~= "argument" or command == nil or argIndex == nil then
|
|
107
115
|
return nil
|
|
108
116
|
end
|
|
109
117
|
local newText = text()
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
if atNextPart and argIndex == commandArgIndex() then
|
|
119
|
+
newText ..= suggestion.title
|
|
120
|
+
elseif not (#suggestion.others == 0) then
|
|
121
|
+
local _exp = suggestion.others[1]
|
|
122
|
+
local _result = currentTextPart()
|
|
123
|
+
if _result ~= nil then
|
|
124
|
+
_result = #_result
|
|
125
|
+
end
|
|
126
|
+
local _condition = _result
|
|
127
|
+
if _condition == nil then
|
|
128
|
+
_condition = 0
|
|
118
129
|
end
|
|
119
|
-
newText
|
|
130
|
+
newText ..= string.sub(_exp, _condition + 1)
|
|
131
|
+
end
|
|
132
|
+
local argNames = getArgumentNames(api.registry, command)
|
|
133
|
+
for i = argIndex + 1, #argNames - 1 do
|
|
134
|
+
newText = `{newText} {argNames[i + 1]}`
|
|
120
135
|
end
|
|
121
136
|
suggestionText(newText)
|
|
122
137
|
end)
|
|
@@ -142,30 +157,37 @@ local function TerminalTextField(_param)
|
|
|
142
157
|
if input.KeyCode ~= Enum.KeyCode.Tab then
|
|
143
158
|
return nil
|
|
144
159
|
end
|
|
145
|
-
--
|
|
160
|
+
-- Command suggestions
|
|
146
161
|
local commandPath = currentCommandPath()
|
|
147
162
|
local suggestion = currentSuggestion()
|
|
163
|
+
if suggestion == nil then
|
|
164
|
+
return nil
|
|
165
|
+
end
|
|
148
166
|
if commandPath == nil then
|
|
149
|
-
local
|
|
150
|
-
if _suggestionTitle ~= nil then
|
|
151
|
-
_suggestionTitle = _suggestionTitle.title
|
|
152
|
-
end
|
|
153
|
-
local suggestionTitle = _suggestionTitle
|
|
154
|
-
if suggestionTitle == nil then
|
|
155
|
-
return nil
|
|
156
|
-
end
|
|
167
|
+
local suggestionTitle = suggestion.title
|
|
157
168
|
local currentText = text()
|
|
158
169
|
local textParts = terminalTextParts()
|
|
159
|
-
|
|
170
|
+
if #textParts == 0 then
|
|
171
|
+
return nil
|
|
172
|
+
end
|
|
173
|
+
local _array = {}
|
|
174
|
+
local _length = #_array
|
|
175
|
+
table.move(textParts, 1, #textParts, _length + 1, _array)
|
|
176
|
+
local pathParts = _array
|
|
177
|
+
local newText = currentText
|
|
160
178
|
if endsWithSpace(currentText) then
|
|
161
|
-
newText
|
|
179
|
+
newText ..= suggestionTitle
|
|
180
|
+
table.insert(pathParts, suggestionTitle)
|
|
162
181
|
elseif not (#textParts == 0) then
|
|
163
|
-
local
|
|
164
|
-
local
|
|
165
|
-
|
|
182
|
+
local lastPartSize = textParts[#textParts]
|
|
183
|
+
local _newText = newText
|
|
184
|
+
local _arg1 = #newText - #lastPartSize
|
|
185
|
+
newText = string.sub(_newText, 0, _arg1) .. suggestionTitle
|
|
186
|
+
local _arg0 = #textParts - 1
|
|
187
|
+
table.remove(pathParts, _arg0 + 1)
|
|
188
|
+
table.insert(pathParts, suggestionTitle)
|
|
166
189
|
end
|
|
167
|
-
local
|
|
168
|
-
local _nextCommand = api.registry:getCommandByString(formatPartsAsPath(suggestionTextParts))
|
|
190
|
+
local _nextCommand = api.registry:getCommandByString(formatPartsAsPath(pathParts))
|
|
169
191
|
if _nextCommand ~= nil then
|
|
170
192
|
_nextCommand = _nextCommand.options
|
|
171
193
|
end
|
|
@@ -174,13 +196,13 @@ local function TerminalTextField(_param)
|
|
|
174
196
|
if not _condition_1 then
|
|
175
197
|
local _result = nextCommand.arguments
|
|
176
198
|
if _result ~= nil then
|
|
177
|
-
_result = #_result
|
|
199
|
+
_result = #_result == 0
|
|
178
200
|
end
|
|
179
201
|
local _condition_2 = _result
|
|
180
202
|
if _condition_2 == nil then
|
|
181
|
-
_condition_2 =
|
|
203
|
+
_condition_2 = true
|
|
182
204
|
end
|
|
183
|
-
_condition_1 = _condition_2
|
|
205
|
+
_condition_1 = not _condition_2
|
|
184
206
|
end
|
|
185
207
|
if _condition_1 then
|
|
186
208
|
newText ..= " "
|
|
@@ -190,11 +212,11 @@ local function TerminalTextField(_param)
|
|
|
190
212
|
textBox.CursorPosition = #newText + 1
|
|
191
213
|
return nil
|
|
192
214
|
end
|
|
193
|
-
--
|
|
215
|
+
-- Argument suggestions
|
|
194
216
|
if commandPath == nil or suggestion == nil or #suggestion.others == 0 then
|
|
195
217
|
return nil
|
|
196
218
|
end
|
|
197
|
-
local argIndex =
|
|
219
|
+
local argIndex = terminalArgIndex()
|
|
198
220
|
local _commandArgs = api.registry:getCommand(commandPath)
|
|
199
221
|
if _commandArgs ~= nil then
|
|
200
222
|
_commandArgs = _commandArgs.options.arguments
|
|
@@ -204,17 +226,20 @@ local function TerminalTextField(_param)
|
|
|
204
226
|
return nil
|
|
205
227
|
end
|
|
206
228
|
local newText = text()
|
|
207
|
-
local parts = terminalTextParts()
|
|
208
|
-
if not endsWithSpace(newText) and not (#parts == 0) then
|
|
209
|
-
local _newText = newText
|
|
210
|
-
local _arg1 = #newText - #parts[#parts]
|
|
211
|
-
newText = string.sub(_newText, 0, _arg1)
|
|
212
|
-
end
|
|
213
229
|
local otherSuggestion = suggestion.others[1]
|
|
214
230
|
if (string.match(otherSuggestion, "%s")) ~= nil then
|
|
215
231
|
otherSuggestion = `"{otherSuggestion}"`
|
|
216
232
|
end
|
|
217
|
-
|
|
233
|
+
local _otherSuggestion = otherSuggestion
|
|
234
|
+
local _result = currentTextPart()
|
|
235
|
+
if _result ~= nil then
|
|
236
|
+
_result = #_result
|
|
237
|
+
end
|
|
238
|
+
local _condition_1 = _result
|
|
239
|
+
if _condition_1 == nil then
|
|
240
|
+
_condition_1 = 0
|
|
241
|
+
end
|
|
242
|
+
newText ..= string.sub(_otherSuggestion, _condition_1 + 1)
|
|
218
243
|
if argIndex < #commandArgs - 1 then
|
|
219
244
|
newText ..= " "
|
|
220
245
|
end
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
2
|
local TS = _G[script]
|
|
3
|
-
local _centurion = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out)
|
|
4
|
-
local ImmutableRegistryPath = _centurion.ImmutableRegistryPath
|
|
5
|
-
local RegistryPath = _centurion.RegistryPath
|
|
6
3
|
local ArrayUtil = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.data).ArrayUtil
|
|
7
4
|
local _string = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.string)
|
|
8
5
|
local endsWithSpace = _string.endsWithSpace
|
|
9
|
-
local
|
|
6
|
+
local splitString = _string.splitString
|
|
10
7
|
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
11
8
|
local Vide = _vide
|
|
12
9
|
local effect = _vide.effect
|
|
@@ -18,21 +15,25 @@ local useHistory = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-
|
|
|
18
15
|
local useMotion = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-motion").useMotion
|
|
19
16
|
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
20
17
|
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
21
|
-
local
|
|
18
|
+
local commandArgIndex = _store.commandArgIndex
|
|
22
19
|
local currentCommandPath = _store.currentCommandPath
|
|
23
20
|
local currentSuggestion = _store.currentSuggestion
|
|
21
|
+
local currentTextPart = _store.currentTextPart
|
|
24
22
|
local interfaceOptions = _store.interfaceOptions
|
|
25
23
|
local mouseOverInterface = _store.mouseOverInterface
|
|
24
|
+
local terminalArgIndex = _store.terminalArgIndex
|
|
26
25
|
local terminalText = _store.terminalText
|
|
27
26
|
local terminalTextParts = _store.terminalTextParts
|
|
28
27
|
local terminalTextValid = _store.terminalTextValid
|
|
29
|
-
local getMissingArgs = TS.import(script, script.Parent.Parent.Parent, "util", "argument").getMissingArgs
|
|
30
|
-
local _suggestion = TS.import(script, script.Parent.Parent.Parent, "util", "suggestion")
|
|
31
|
-
local getArgumentSuggestion = _suggestion.getArgumentSuggestion
|
|
32
|
-
local getCommandSuggestion = _suggestion.getCommandSuggestion
|
|
33
28
|
local HistoryList = TS.import(script, script.Parent.Parent, "history").HistoryList
|
|
34
29
|
local Frame = TS.import(script, script.Parent.Parent, "ui", "frame").Frame
|
|
35
30
|
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
31
|
+
local _command = TS.import(script, script.Parent, "command")
|
|
32
|
+
local getMissingArgs = _command.getMissingArgs
|
|
33
|
+
local getValidPath = _command.getValidPath
|
|
34
|
+
local _suggestion = TS.import(script, script.Parent, "suggestion")
|
|
35
|
+
local getArgumentSuggestion = _suggestion.getArgumentSuggestion
|
|
36
|
+
local getCommandSuggestion = _suggestion.getCommandSuggestion
|
|
36
37
|
local TerminalTextField = TS.import(script, script.Parent, "terminal-text-field").TerminalTextField
|
|
37
38
|
local MAX_HEIGHT = HISTORY_TEXT_SIZE * 10
|
|
38
39
|
local TEXT_FIELD_HEIGHT = 40
|
|
@@ -103,112 +104,141 @@ local function Terminal()
|
|
|
103
104
|
onTextChange = function(text)
|
|
104
105
|
terminalText(text)
|
|
105
106
|
terminalTextValid(false)
|
|
107
|
+
missingArgs({})
|
|
106
108
|
local parts = terminalTextParts()
|
|
107
109
|
if #parts == 0 then
|
|
108
110
|
currentCommandPath(nil)
|
|
109
111
|
currentSuggestion(nil)
|
|
110
|
-
|
|
112
|
+
terminalArgIndex(nil)
|
|
111
113
|
return nil
|
|
112
114
|
end
|
|
113
115
|
-- If the text ends in a space, we want to count that as having traversed
|
|
114
|
-
-- to the next "part" of the text.
|
|
115
|
-
-- text part as part of the parent path.
|
|
116
|
+
-- to the next "part" of the text.
|
|
116
117
|
local atNextPart = endsWithSpace(text)
|
|
117
|
-
local
|
|
118
|
-
local
|
|
119
|
-
if
|
|
120
|
-
--
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
else
|
|
126
|
-
local currentPath = RegistryPath:empty()
|
|
127
|
-
for _, part in parts do
|
|
128
|
-
currentPath:append(part)
|
|
129
|
-
if api.registry:getCommand(currentPath) ~= nil then
|
|
130
|
-
atCommand = true
|
|
131
|
-
break
|
|
132
|
-
end
|
|
133
|
-
if #api.registry:getChildPaths(currentPath) == 0 then
|
|
134
|
-
atCommand = false
|
|
135
|
-
break
|
|
136
|
-
end
|
|
118
|
+
local path = getValidPath(api.registry, parts)
|
|
119
|
+
local command = if path ~= nil then api.registry:getCommand(path) else nil
|
|
120
|
+
if command ~= nil then
|
|
121
|
+
-- Check for missing arguments
|
|
122
|
+
local missing = getMissingArgs(command, parts)
|
|
123
|
+
local _result = command.options.arguments
|
|
124
|
+
if _result ~= nil then
|
|
125
|
+
_result = #_result == 0
|
|
137
126
|
end
|
|
138
|
-
|
|
139
|
-
end
|
|
140
|
-
local currentPath = currentCommandPath()
|
|
141
|
-
if not atCommand and currentPath ~= nil then
|
|
142
|
-
currentCommandPath(nil)
|
|
143
|
-
elseif atCommand and commandPath ~= currentPath then
|
|
144
|
-
currentCommandPath(commandPath)
|
|
145
|
-
end
|
|
146
|
-
local _result
|
|
147
|
-
if commandPath ~= nil then
|
|
148
|
-
local _result_1 = api.registry:getCommand(commandPath)
|
|
149
|
-
if _result_1 ~= nil then
|
|
150
|
-
_result_1 = _result_1.options
|
|
151
|
-
end
|
|
152
|
-
_result = _result_1
|
|
153
|
-
else
|
|
154
|
-
_result = nil
|
|
155
|
-
end
|
|
156
|
-
local command = _result
|
|
157
|
-
if commandPath ~= nil and command ~= nil then
|
|
158
|
-
local missing = getMissingArgs(api.registry, commandPath, parts)
|
|
159
|
-
missingArgs(missing)
|
|
160
|
-
local _result_1 = command.arguments
|
|
161
|
-
if _result_1 ~= nil then
|
|
162
|
-
_result_1 = #_result_1 == 0
|
|
163
|
-
end
|
|
164
|
-
local _condition = _result_1
|
|
127
|
+
local _condition = _result
|
|
165
128
|
if _condition == nil then
|
|
166
129
|
_condition = true
|
|
167
130
|
end
|
|
168
131
|
local noArgs = _condition
|
|
132
|
+
currentCommandPath(path)
|
|
133
|
+
missingArgs(missing)
|
|
169
134
|
terminalTextValid(noArgs or #missing == 0 or (atNextPart and #missing == 1))
|
|
170
135
|
else
|
|
171
136
|
terminalTextValid(false)
|
|
172
137
|
end
|
|
173
|
-
|
|
174
|
-
local
|
|
175
|
-
|
|
176
|
-
if
|
|
177
|
-
|
|
178
|
-
if
|
|
179
|
-
|
|
138
|
+
local textPart = if not atNextPart then parts[#parts] else nil
|
|
139
|
+
local argIndex = if path ~= nil then #parts - path:size() - (if atNextPart then 0 else 1) else -1
|
|
140
|
+
terminalArgIndex(argIndex)
|
|
141
|
+
if command == nil or argIndex == -1 then
|
|
142
|
+
-- Get command suggestions
|
|
143
|
+
local index = #parts - (if atNextPart then 1 else 2)
|
|
144
|
+
local _parentPath = path
|
|
145
|
+
if _parentPath ~= nil then
|
|
146
|
+
_parentPath = _parentPath:slice(0, index)
|
|
147
|
+
end
|
|
148
|
+
local parentPath = _parentPath
|
|
149
|
+
local _exp = api.registry
|
|
150
|
+
local _result = parentPath
|
|
151
|
+
if _result ~= nil then
|
|
152
|
+
_result = _result:isEmpty()
|
|
153
|
+
end
|
|
154
|
+
currentSuggestion(getCommandSuggestion(_exp, if not _result then parentPath else nil, textPart))
|
|
155
|
+
currentTextPart(textPart)
|
|
156
|
+
return nil
|
|
157
|
+
end
|
|
158
|
+
-- Handle arguments
|
|
159
|
+
local args = command.options.arguments
|
|
160
|
+
if args == nil then
|
|
161
|
+
currentSuggestion(nil)
|
|
162
|
+
currentTextPart(nil)
|
|
163
|
+
commandArgIndex(nil)
|
|
164
|
+
return nil
|
|
165
|
+
end
|
|
166
|
+
local index = -1
|
|
167
|
+
local currentArg
|
|
168
|
+
local endIndex = -1
|
|
169
|
+
for i = 0, argIndex do
|
|
170
|
+
if endIndex == nil or i <= endIndex then
|
|
171
|
+
continue
|
|
180
172
|
end
|
|
181
|
-
|
|
173
|
+
index += 1
|
|
174
|
+
if index >= #args then
|
|
175
|
+
currentArg = nil
|
|
176
|
+
break
|
|
177
|
+
end
|
|
178
|
+
currentArg = args[index + 1]
|
|
179
|
+
local _condition = currentArg.numArgs
|
|
182
180
|
if _condition == nil then
|
|
183
|
-
_condition =
|
|
181
|
+
_condition = 1
|
|
184
182
|
end
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
local numArgs = _condition
|
|
184
|
+
endIndex = if numArgs ~= "rest" then i + (numArgs - 1) else nil
|
|
185
|
+
end
|
|
186
|
+
local _registry = api.registry
|
|
187
|
+
local _result = currentArg
|
|
188
|
+
if _result ~= nil then
|
|
189
|
+
_result = _result.type
|
|
190
|
+
end
|
|
191
|
+
local _condition = _result
|
|
192
|
+
if _condition == nil then
|
|
193
|
+
_condition = ""
|
|
188
194
|
end
|
|
189
|
-
local
|
|
190
|
-
|
|
195
|
+
local argType = _registry:getType(_condition)
|
|
196
|
+
if currentArg == nil or argType == nil then
|
|
197
|
+
currentSuggestion(nil)
|
|
198
|
+
currentTextPart(nil)
|
|
199
|
+
terminalArgIndex(nil)
|
|
200
|
+
commandArgIndex(nil)
|
|
201
|
+
return nil
|
|
202
|
+
end
|
|
203
|
+
commandArgIndex(index)
|
|
204
|
+
local argTextPart
|
|
191
205
|
local suggestion
|
|
192
|
-
if
|
|
193
|
-
|
|
194
|
-
suggestion =
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if _result_2 ~= nil then
|
|
205
|
-
_result_2 = _result_2.error
|
|
206
|
+
if argType.kind == "single" then
|
|
207
|
+
argTextPart = textPart
|
|
208
|
+
suggestion = getArgumentSuggestion({
|
|
209
|
+
kind = "single",
|
|
210
|
+
options = currentArg,
|
|
211
|
+
type = argType,
|
|
212
|
+
input = textPart,
|
|
213
|
+
}, textPart)
|
|
214
|
+
else
|
|
215
|
+
local _condition_1 = textPart
|
|
216
|
+
if _condition_1 == nil then
|
|
217
|
+
_condition_1 = ""
|
|
206
218
|
end
|
|
207
|
-
|
|
208
|
-
|
|
219
|
+
local textParts = splitString(_condition_1, ",")
|
|
220
|
+
local lastPart = if not (#textParts == 0) then textParts[#textParts] else nil
|
|
221
|
+
local _result_1 = textPart
|
|
222
|
+
if _result_1 ~= nil then
|
|
223
|
+
_result_1 = string.sub(_result_1, -1)
|
|
209
224
|
end
|
|
225
|
+
argTextPart = if _result_1 ~= "," then lastPart else nil
|
|
226
|
+
suggestion = getArgumentSuggestion({
|
|
227
|
+
kind = "list",
|
|
228
|
+
options = currentArg,
|
|
229
|
+
type = argType,
|
|
230
|
+
input = textParts,
|
|
231
|
+
}, argTextPart)
|
|
210
232
|
end
|
|
233
|
+
currentTextPart(argTextPart)
|
|
211
234
|
currentSuggestion(suggestion)
|
|
235
|
+
local _result_1 = suggestion
|
|
236
|
+
if _result_1 ~= nil then
|
|
237
|
+
_result_1 = _result_1.error
|
|
238
|
+
end
|
|
239
|
+
if _result_1 ~= nil then
|
|
240
|
+
terminalTextValid(false)
|
|
241
|
+
end
|
|
212
242
|
end,
|
|
213
243
|
onSubmit = function()
|
|
214
244
|
local commandPath = currentCommandPath()
|
package/out/store.d.ts
CHANGED
|
@@ -4,9 +4,10 @@ export declare const interfaceVisible: import("@rbxts/charm").Atom<boolean>;
|
|
|
4
4
|
export declare const interfaceOptions: import("@rbxts/charm").Atom<import("./types").InterfaceOptions>;
|
|
5
5
|
export declare const mouseOverInterface: import("@rbxts/charm").Atom<boolean>;
|
|
6
6
|
export declare const currentCommandPath: import("@rbxts/charm").Atom<ImmutableRegistryPath | undefined>;
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const commandArgIndex: import("@rbxts/charm").Atom<number | undefined>;
|
|
8
|
+
export declare const terminalArgIndex: import("@rbxts/charm").Atom<number | undefined>;
|
|
8
9
|
export declare const currentSuggestion: import("@rbxts/charm").Atom<Suggestion | undefined>;
|
|
9
10
|
export declare const terminalText: import("@rbxts/charm").Atom<string>;
|
|
10
11
|
export declare const terminalTextParts: import("@rbxts/charm").Molecule<string[]>;
|
|
11
|
-
export declare const currentTextPart: import("@rbxts/charm").Molecule<string | undefined>;
|
|
12
12
|
export declare const terminalTextValid: import("@rbxts/charm").Atom<boolean>;
|
|
13
|
+
export declare const currentTextPart: import("@rbxts/charm").Atom<string | undefined>;
|
package/out/store.lua
CHANGED
|
@@ -9,32 +9,25 @@ local interfaceVisible = atom(false)
|
|
|
9
9
|
local interfaceOptions = atom(DEFAULT_INTERFACE_OPTIONS)
|
|
10
10
|
local mouseOverInterface = atom(false)
|
|
11
11
|
local currentCommandPath = atom(nil)
|
|
12
|
-
local
|
|
12
|
+
local commandArgIndex = atom(nil)
|
|
13
|
+
local terminalArgIndex = atom(nil)
|
|
13
14
|
local currentSuggestion = atom(nil)
|
|
14
15
|
local terminalText = atom("")
|
|
15
16
|
local terminalTextParts = computed(function()
|
|
16
17
|
return splitString(terminalText(), " ")
|
|
17
18
|
end)
|
|
18
|
-
local currentTextPart = computed(function()
|
|
19
|
-
local text = terminalText()
|
|
20
|
-
local textParts = terminalTextParts()
|
|
21
|
-
local endsWithSpace = #textParts > 0 and #{ string.match(text, "%s$") } > 0
|
|
22
|
-
local index = if endsWithSpace then #textParts else #textParts - 1
|
|
23
|
-
if index == -1 or index >= #textParts then
|
|
24
|
-
return nil
|
|
25
|
-
end
|
|
26
|
-
return textParts[index + 1]
|
|
27
|
-
end)
|
|
28
19
|
local terminalTextValid = atom(false)
|
|
20
|
+
local currentTextPart = atom(nil)
|
|
29
21
|
return {
|
|
30
22
|
interfaceVisible = interfaceVisible,
|
|
31
23
|
interfaceOptions = interfaceOptions,
|
|
32
24
|
mouseOverInterface = mouseOverInterface,
|
|
33
25
|
currentCommandPath = currentCommandPath,
|
|
34
|
-
|
|
26
|
+
commandArgIndex = commandArgIndex,
|
|
27
|
+
terminalArgIndex = terminalArgIndex,
|
|
35
28
|
currentSuggestion = currentSuggestion,
|
|
36
29
|
terminalText = terminalText,
|
|
37
30
|
terminalTextParts = terminalTextParts,
|
|
38
|
-
currentTextPart = currentTextPart,
|
|
39
31
|
terminalTextValid = terminalTextValid,
|
|
32
|
+
currentTextPart = currentTextPart,
|
|
40
33
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbxts/centurion-ui",
|
|
3
3
|
"description": "Terminal UI for the Centurion command framework",
|
|
4
|
-
"version": "1.0.0-dev-
|
|
4
|
+
"version": "1.0.0-dev-84057f1",
|
|
5
5
|
"author": "paradoxuum",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "out/init.lua",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"dev": "shx rm -rf out && rbxtsc -w"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@rbxts/centurion": "^1.0.0-dev-
|
|
35
|
+
"@rbxts/centurion": "^1.0.0-dev-84057f1",
|
|
36
36
|
"@rbxts/compiler-types": "2.3.0-types.1",
|
|
37
|
-
"@rbxts/types": "^1.0.
|
|
37
|
+
"@rbxts/types": "^1.0.794",
|
|
38
38
|
"roblox-ts": "2.3.0-dev-26ec859",
|
|
39
39
|
"shx": "^0.3.4",
|
|
40
40
|
"typescript": "~5.5.4"
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@rbxts/vide": "^0.4.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@rbxts/centurion": "
|
|
50
|
+
"@rbxts/centurion": "*"
|
|
51
51
|
},
|
|
52
52
|
"stableVersion": "1.0.0"
|
|
53
53
|
}
|
package/out/util/argument.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { BaseRegistry, ImmutableRegistryPath, RegistryPath } from "@rbxts/centurion";
|
|
2
|
-
export declare function getArgumentNames(registry: BaseRegistry, path: RegistryPath): string[];
|
|
3
|
-
export declare function getMissingArgs(registry: BaseRegistry, path: ImmutableRegistryPath, text: string[]): string[];
|
package/out/util/argument.lua
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local IS_EDIT = TS.import(script, script.Parent.Parent, "constants", "util").IS_EDIT
|
|
4
|
-
local function getArgumentNames(registry, path)
|
|
5
|
-
if IS_EDIT then
|
|
6
|
-
return {}
|
|
7
|
-
end
|
|
8
|
-
local command = registry:getCommand(path)
|
|
9
|
-
if command == nil or command.options.arguments == nil then
|
|
10
|
-
return {}
|
|
11
|
-
end
|
|
12
|
-
local _exp = command.options.arguments
|
|
13
|
-
-- ▼ ReadonlyArray.map ▼
|
|
14
|
-
local _newValue = table.create(#_exp)
|
|
15
|
-
local _callback = function(arg)
|
|
16
|
-
return arg.name
|
|
17
|
-
end
|
|
18
|
-
for _k, _v in _exp do
|
|
19
|
-
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
20
|
-
end
|
|
21
|
-
-- ▲ ReadonlyArray.map ▲
|
|
22
|
-
return _newValue
|
|
23
|
-
end
|
|
24
|
-
local function getMissingArgs(registry, path, text)
|
|
25
|
-
local _commandOptions = registry:getCommand(path)
|
|
26
|
-
if _commandOptions ~= nil then
|
|
27
|
-
_commandOptions = _commandOptions.options
|
|
28
|
-
end
|
|
29
|
-
local commandOptions = _commandOptions
|
|
30
|
-
if commandOptions == nil or commandOptions.arguments == nil or #commandOptions.arguments == 0 then
|
|
31
|
-
return {}
|
|
32
|
-
end
|
|
33
|
-
local lastPartIndex = #text - path:size() - 1
|
|
34
|
-
local missingArgs = {}
|
|
35
|
-
local index = 0
|
|
36
|
-
for _, arg in commandOptions.arguments do
|
|
37
|
-
if arg.optional then
|
|
38
|
-
break
|
|
39
|
-
end
|
|
40
|
-
if index > lastPartIndex then
|
|
41
|
-
local _name = arg.name
|
|
42
|
-
table.insert(missingArgs, _name)
|
|
43
|
-
end
|
|
44
|
-
index += 1
|
|
45
|
-
end
|
|
46
|
-
return missingArgs
|
|
47
|
-
end
|
|
48
|
-
return {
|
|
49
|
-
getArgumentNames = getArgumentNames,
|
|
50
|
-
getMissingArgs = getMissingArgs,
|
|
51
|
-
}
|
package/out/util/suggestion.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { BaseRegistry, RegistryPath } from "@rbxts/centurion";
|
|
2
|
-
import { ArgumentSuggestion, Suggestion } from "../types";
|
|
3
|
-
export declare function getArgumentSuggestion(registry: BaseRegistry, path: RegistryPath, index: number, text?: string): ArgumentSuggestion | undefined;
|
|
4
|
-
export declare function getCommandSuggestion(registry: BaseRegistry, parentPath?: RegistryPath, text?: string): Suggestion | undefined;
|
package/out/util/suggestion.lua
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local ArrayUtil = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.data).ArrayUtil
|
|
4
|
-
local Players = TS.import(script, TS.getModule(script, "@rbxts", "services")).Players
|
|
5
|
-
local MAX_OTHER_SUGGESTIONS = 3
|
|
6
|
-
local function getSortedIndices(max, strings, text)
|
|
7
|
-
-- If no text is provided, sort alphabetically
|
|
8
|
-
if text == nil then
|
|
9
|
-
local _array = {}
|
|
10
|
-
local _length = #_array
|
|
11
|
-
table.move(strings, 1, #strings, _length + 1, _array)
|
|
12
|
-
table.sort(_array)
|
|
13
|
-
-- ▼ ReadonlyArray.map ▼
|
|
14
|
-
local _newValue = table.create(#_array)
|
|
15
|
-
local _callback = function(_, index)
|
|
16
|
-
return index
|
|
17
|
-
end
|
|
18
|
-
for _k, _v in _array do
|
|
19
|
-
_newValue[_k] = _callback(_v, _k - 1, _array)
|
|
20
|
-
end
|
|
21
|
-
-- ▲ ReadonlyArray.map ▲
|
|
22
|
-
local sorted = _newValue
|
|
23
|
-
return ArrayUtil.slice(sorted, 0, math.min(#sorted, max))
|
|
24
|
-
end
|
|
25
|
-
-- Otherwise, sort by the closest match
|
|
26
|
-
local textLower = string.lower(text)
|
|
27
|
-
local textEndIndex = #text
|
|
28
|
-
local results = {}
|
|
29
|
-
for i = 0, #strings - 1 do
|
|
30
|
-
local part = string.sub(string.lower(strings[i + 1]), 0, textEndIndex)
|
|
31
|
-
if part == textLower then
|
|
32
|
-
local _arg0 = { #part, i }
|
|
33
|
-
table.insert(results, _arg0)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
table.sort(results, function(a, b)
|
|
37
|
-
if a[1] == b[1] then
|
|
38
|
-
return strings[a[2] + 1] < strings[b[2] + 1]
|
|
39
|
-
end
|
|
40
|
-
return a[1] < b[1]
|
|
41
|
-
end)
|
|
42
|
-
local _exp = ArrayUtil.slice(results, 0, math.min(#results, max))
|
|
43
|
-
-- ▼ ReadonlyArray.map ▼
|
|
44
|
-
local _newValue = table.create(#_exp)
|
|
45
|
-
local _callback = function(val)
|
|
46
|
-
return val[2]
|
|
47
|
-
end
|
|
48
|
-
for _k, _v in _exp do
|
|
49
|
-
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
50
|
-
end
|
|
51
|
-
-- ▲ ReadonlyArray.map ▲
|
|
52
|
-
return _newValue
|
|
53
|
-
end
|
|
54
|
-
local function getArgumentSuggestion(registry, path, index, text)
|
|
55
|
-
local command = registry:getCommand(path)
|
|
56
|
-
if command == nil then
|
|
57
|
-
return nil
|
|
58
|
-
end
|
|
59
|
-
local args = command.options.arguments
|
|
60
|
-
if args == nil or #args == 0 then
|
|
61
|
-
return nil
|
|
62
|
-
end
|
|
63
|
-
if index < 0 or index >= #args then
|
|
64
|
-
return nil
|
|
65
|
-
end
|
|
66
|
-
local arg = args[index + 1]
|
|
67
|
-
local typeObject = registry:getType(arg.type)
|
|
68
|
-
if typeObject == nil then
|
|
69
|
-
return nil
|
|
70
|
-
end
|
|
71
|
-
local _result
|
|
72
|
-
if arg.suggestions ~= nil then
|
|
73
|
-
local _array = {}
|
|
74
|
-
local _length = #_array
|
|
75
|
-
local _array_1 = arg.suggestions
|
|
76
|
-
table.move(_array_1, 1, #_array_1, _length + 1, _array)
|
|
77
|
-
_result = _array
|
|
78
|
-
else
|
|
79
|
-
_result = {}
|
|
80
|
-
end
|
|
81
|
-
local argSuggestions = _result
|
|
82
|
-
if typeObject.suggestions ~= nil then
|
|
83
|
-
local _condition = text
|
|
84
|
-
if _condition == nil then
|
|
85
|
-
_condition = ""
|
|
86
|
-
end
|
|
87
|
-
for _, suggestion in typeObject.suggestions(_condition, Players.LocalPlayer) do
|
|
88
|
-
table.insert(argSuggestions, suggestion)
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
-- If the type is not marked as "expensive", transform the text into the type
|
|
92
|
-
-- If the transformation fails, include the error message in the suggestion
|
|
93
|
-
local errorText
|
|
94
|
-
local success, err = pcall(function()
|
|
95
|
-
if typeObject.expensive then
|
|
96
|
-
return nil
|
|
97
|
-
end
|
|
98
|
-
local _condition = text
|
|
99
|
-
if _condition == nil then
|
|
100
|
-
_condition = ""
|
|
101
|
-
end
|
|
102
|
-
local transformResult = typeObject.transform(_condition, Players.LocalPlayer)
|
|
103
|
-
if transformResult.ok then
|
|
104
|
-
return nil
|
|
105
|
-
end
|
|
106
|
-
errorText = transformResult.value
|
|
107
|
-
end)
|
|
108
|
-
if not success then
|
|
109
|
-
errorText = "Failed to transform argument"
|
|
110
|
-
warn(err)
|
|
111
|
-
end
|
|
112
|
-
local _exp = getSortedIndices(MAX_OTHER_SUGGESTIONS, argSuggestions, text)
|
|
113
|
-
-- ▼ ReadonlyArray.map ▼
|
|
114
|
-
local _newValue = table.create(#_exp)
|
|
115
|
-
local _callback = function(index)
|
|
116
|
-
return argSuggestions[index + 1]
|
|
117
|
-
end
|
|
118
|
-
for _k, _v in _exp do
|
|
119
|
-
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
120
|
-
end
|
|
121
|
-
-- ▲ ReadonlyArray.map ▲
|
|
122
|
-
local otherSuggestions = _newValue
|
|
123
|
-
local _object = {
|
|
124
|
-
type = "argument",
|
|
125
|
-
title = arg.name,
|
|
126
|
-
others = otherSuggestions,
|
|
127
|
-
description = arg.description,
|
|
128
|
-
dataType = typeObject.name,
|
|
129
|
-
}
|
|
130
|
-
local _left = "optional"
|
|
131
|
-
local _condition = arg.optional
|
|
132
|
-
if _condition == nil then
|
|
133
|
-
_condition = false
|
|
134
|
-
end
|
|
135
|
-
_object[_left] = _condition
|
|
136
|
-
_object.error = errorText
|
|
137
|
-
return _object
|
|
138
|
-
end
|
|
139
|
-
local function getCommandSuggestion(registry, parentPath, text)
|
|
140
|
-
local paths = if parentPath ~= nil then registry:getChildPaths(parentPath) else registry:getRootPaths()
|
|
141
|
-
if #paths == 0 then
|
|
142
|
-
return nil
|
|
143
|
-
end
|
|
144
|
-
-- ▼ ReadonlyArray.map ▼
|
|
145
|
-
local _newValue = table.create(#paths)
|
|
146
|
-
local _callback = function(path)
|
|
147
|
-
return path:tail()
|
|
148
|
-
end
|
|
149
|
-
for _k, _v in paths do
|
|
150
|
-
_newValue[_k] = _callback(_v, _k - 1, paths)
|
|
151
|
-
end
|
|
152
|
-
-- ▲ ReadonlyArray.map ▲
|
|
153
|
-
local pathNames = _newValue
|
|
154
|
-
local sortedPaths = getSortedIndices(MAX_OTHER_SUGGESTIONS + 1, pathNames, text)
|
|
155
|
-
if #sortedPaths == 0 then
|
|
156
|
-
return nil
|
|
157
|
-
end
|
|
158
|
-
local firstPath = paths[sortedPaths[1] + 1]
|
|
159
|
-
local _result = registry:getCommand(firstPath)
|
|
160
|
-
if _result ~= nil then
|
|
161
|
-
_result = _result.options
|
|
162
|
-
end
|
|
163
|
-
local _condition = _result
|
|
164
|
-
if _condition == nil then
|
|
165
|
-
local _result_1 = registry:getGroup(firstPath)
|
|
166
|
-
if _result_1 ~= nil then
|
|
167
|
-
_result_1 = _result_1.options
|
|
168
|
-
end
|
|
169
|
-
_condition = _result_1
|
|
170
|
-
end
|
|
171
|
-
local mainData = _condition
|
|
172
|
-
if mainData == nil then
|
|
173
|
-
return nil
|
|
174
|
-
end
|
|
175
|
-
local _result_1
|
|
176
|
-
if #sortedPaths > 1 then
|
|
177
|
-
local _exp = ArrayUtil.slice(sortedPaths, 1)
|
|
178
|
-
-- ▼ ReadonlyArray.map ▼
|
|
179
|
-
local _newValue_1 = table.create(#_exp)
|
|
180
|
-
local _callback_1 = function(index)
|
|
181
|
-
return pathNames[index + 1]
|
|
182
|
-
end
|
|
183
|
-
for _k, _v in _exp do
|
|
184
|
-
_newValue_1[_k] = _callback_1(_v, _k - 1, _exp)
|
|
185
|
-
end
|
|
186
|
-
-- ▲ ReadonlyArray.map ▲
|
|
187
|
-
_result_1 = _newValue_1
|
|
188
|
-
else
|
|
189
|
-
_result_1 = {}
|
|
190
|
-
end
|
|
191
|
-
local otherNames = _result_1
|
|
192
|
-
return {
|
|
193
|
-
type = "command",
|
|
194
|
-
title = firstPath:tail(),
|
|
195
|
-
others = otherNames,
|
|
196
|
-
description = mainData.description,
|
|
197
|
-
shortcuts = mainData.shortcuts,
|
|
198
|
-
}
|
|
199
|
-
end
|
|
200
|
-
return {
|
|
201
|
-
getArgumentSuggestion = getArgumentSuggestion,
|
|
202
|
-
getCommandSuggestion = getCommandSuggestion,
|
|
203
|
-
}
|