Skip to content

Commit 9eb145b

Browse files
committed
add autocomplete
add small interface when scm is run directly without args
1 parent 756d6cc commit 9eb145b

File tree

2 files changed

+186
-4
lines changed

2 files changed

+186
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Shows all installed scripts.
3737
Shows all available configurations.
3838
- `<name>`: Shows the value of a specific configuration.
3939
- `<name> <value>`: Updates the value of a specific configuration.
40+
## refresh
41+
Downloads the names of all programs and libraries of the official repository.
42+
Refreshes autocomplete.
4043
## help
4144
Shows all available commands and their description.
4245
- `<name>`: Shows the description of a command by name.

scm.lua

Lines changed: 183 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ scm.config = {
1212
["programSuffix"] = "-prog",
1313
["librarySuffix"] = "-lib",
1414
["infoFile"] = "files.txt", -- provides the structure of a git repo (paths to all files)
15+
["apiGithubGetRepos"] = "https://api.github.com/orgs/mc-cc-scripts/repos?type=all&per_page=100&page=1",
1516
-- Local Settings
1617
["installScript"] = "1kKZ8zTS",
1718
["rootDirectory"] = "",
@@ -24,7 +25,8 @@ scm.config = {
2425
["printPrefix"] = "[scm] ",
2526
["logDate"] = false,
2627
["writeLogFile"] = false,
27-
["logFilePath"] = "logs/scm-log.txt"
28+
["logFilePath"] = "logs/scm-log.txt",
29+
["repoScriptsFile"] = "scm-repo-scripts.txt" -- will be saved in configDirectory as well
2830
}
2931
----------------
3032

@@ -130,6 +132,16 @@ $ config <name> <value>
130132
Updates the configuration
131133
]]
132134
},
135+
["refresh"] = {
136+
func = function (args)
137+
scm:refreshAutocomplete()
138+
end,
139+
description = [[
140+
$ refresh
141+
Downloads the names of all programs and libraries of the official repository.
142+
Refreshes autocomplete.
143+
]]
144+
},
133145
["help"] = {
134146
---@param args table
135147
func = function (args)
@@ -152,6 +164,133 @@ $ help <name>
152164
}
153165
}
154166

167+
function scm:refreshRepoScripts ()
168+
self:log("Downloading program and library names from GitHub...")
169+
local repoScripts = {}
170+
171+
local programs = {}
172+
local libraries = {}
173+
174+
local request = http.get(self.config["apiGithubGetRepos"])
175+
if request then
176+
local response = request.readAll()
177+
request.close()
178+
179+
local responseTable = textutils.unserializeJSON(response)
180+
for i = 1, #responseTable, 1 do
181+
if string.sub(responseTable[i]["name"], -string.len(self.config["programSuffix"])) == self.config["programSuffix"] then
182+
programs[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["programSuffix"]))] = {}
183+
elseif string.sub(responseTable[i]["name"], -string.len(self.config["librarySuffix"])) == self.config["librarySuffix"] then
184+
libraries[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["librarySuffix"]))] = {}
185+
end
186+
end
187+
scm:log("Done")
188+
else
189+
scm:log("Download failed")
190+
end
191+
192+
self.commands["add"]["args"] = programs
193+
self.commands["require"]["args"] = libraries
194+
195+
repoScripts["libraries"] = libraries
196+
repoScripts["programs"] = programs
197+
198+
local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "w")
199+
if file then
200+
file.write(textutils.serializeJSON(repoScripts))
201+
file.close()
202+
end
203+
end
204+
205+
function scm:loadRepoScripts ()
206+
local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "r")
207+
208+
if not file then
209+
self:refreshRepoScripts()
210+
else
211+
local repoScripts = textutils.unserializeJSON(file.readAll()) or nil
212+
if repoScripts then
213+
self.commands["add"]["args"] = repoScripts["programs"]
214+
self.commands["require"]["args"] = repoScripts["libraries"]
215+
end
216+
217+
file.close()
218+
end
219+
end
220+
221+
function scm:prepareAutocomplete ()
222+
-- prepare update and remove
223+
scm:loadScripts()
224+
local installedScripts = {}
225+
for i = 1, #self.scripts, 1 do
226+
installedScripts[self.scripts[i].name] = {}
227+
end
228+
installedScripts["all"] = {}
229+
230+
self.commands["update"]["args"] = installedScripts
231+
self.commands["remove"]["args"] = installedScripts
232+
233+
-- prepare add and require
234+
self:loadRepoScripts()
235+
236+
-- prepare config
237+
local availableConfigs = {}
238+
239+
for k, _ in pairs(self.config) do
240+
availableConfigs[k] = {}
241+
end
242+
243+
self.commands["config"]["args"] = availableConfigs
244+
245+
-- prepare help
246+
local availableCommands = {}
247+
248+
for k, _ in pairs(self.commands) do
249+
availableCommands[k] = {}
250+
end
251+
252+
self.commands["help"]["args"] = availableCommands
253+
end
254+
255+
---@param shell table
256+
---@param index integer
257+
---@param argument string
258+
---@param previous table
259+
---@return table | nil
260+
local function completionFunction (shell, index, argument, previous)
261+
local commands = {}
262+
for k, _ in pairs(scm.commands) do
263+
commands[k] = scm.commands[k]["args"] or {}
264+
end
265+
266+
local currArg = commands
267+
for i = 2, #previous do
268+
if currArg[previous[i]] then
269+
currArg = currArg[previous[i]]
270+
else
271+
return nil
272+
end
273+
end
274+
275+
local results = {}
276+
for word, _ in pairs(currArg) do
277+
if word:sub(1, #argument) == argument then
278+
results[#results+1] = word:sub(#argument + 1)
279+
end
280+
end
281+
return results;
282+
end
283+
284+
local function updateAutocomplete ()
285+
shell.setCompletionFunction("scm", completionFunction)
286+
end
287+
288+
function scm:refreshAutocomplete ()
289+
scm:refreshRepoScripts()
290+
scm:prepareAutocomplete()
291+
updateAutocomplete()
292+
end
293+
155294
---@param message string
156295
function scm:log (message)
157296
local datetime = ""
@@ -392,21 +531,30 @@ function scm:addScript (sourceObject, success)
392531
if self.scripts[i].source[sourceObject.sourceName] then
393532
self.scripts[i].source[sourceObject.sourceName] = sourceObject.source[sourceObject.sourceName]
394533
self:saveScripts()
395-
534+
396535
return true
397536
end
398537
end
399538
end
400539

401540
if not scriptExists then
402541
scm:log("Script added: " .. sourceObject.name)
403-
table.insert(self.scripts, sourceObject)
542+
table.insert(self.scripts, sourceObject)
404543
else
405544
scm:log("Script already exists.")
545+
return false
406546
end
407-
547+
408548
self:saveScripts()
409549

550+
-- update for autocomplete
551+
self.commands["update"]["args"] = self.commands["update"]["args"] or {}
552+
self.commands["remove"]["args"] = self.commands["remove"]["args"] or {}
553+
self.commands["update"]["args"][sourceObject.name] = {}
554+
self.commands["remove"]["args"][sourceObject.name] = {}
555+
self:prepareAutocomplete()
556+
updateAutocomplete()
557+
410558
return true
411559
end
412560

@@ -454,6 +602,7 @@ function scm:removeScript (name, keepScriptConfig)
454602
self:saveScripts()
455603
end
456604

605+
-- delete file
457606
if scriptType and fs.exists(self.config[scriptType .. "Directory"] .. name .. ".lua") then
458607
fs.delete(self.config[scriptType .. "Directory"] .. name .. self.config[scriptType .. "Suffix"])
459608
if scriptType == "library" then
@@ -464,6 +613,10 @@ function scm:removeScript (name, keepScriptConfig)
464613
if scriptType == "program" then
465614
fs.delete(name)
466615
end
616+
617+
-- update autocomplete
618+
self:prepareAutocomplete()
619+
updateAutocomplete()
467620
end
468621

469622
function scm:removeAllScripts ()
@@ -691,6 +844,32 @@ end
691844

692845
---@param args table
693846
function scm:handleArguments (args)
847+
if #args == 0 then
848+
-- enable autocomplete
849+
self:prepareAutocomplete()
850+
updateAutocomplete()
851+
852+
-- some interface
853+
local _, cursorY = term.getCursorPos()
854+
term.setCursorPos(0, cursorY)
855+
term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444")
856+
term.setCursorPos(0, cursorY)
857+
term.scroll(1)
858+
term.blit(" SCM - Script Manager ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444")
859+
term.setCursorPos(0, cursorY)
860+
term.scroll(1)
861+
term.blit(" Autocomplete enabled. ","777777777777777777777777777777777","444444444444444444444444444444444")
862+
term.setCursorPos(0, cursorY)
863+
term.scroll(1)
864+
term.blit(" Type `scm help` to learn more. ","77777777ffffffff77777777777777777","444444444444444444444444444444444")
865+
term.setCursorPos(0, cursorY)
866+
term.scroll(1)
867+
term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444")
868+
term.setCursorPos(0, cursorY)
869+
term.scroll(2)
870+
return
871+
end
872+
694873
if args[1] and self.commands[args[1]] then
695874
self.commands[args[1]]["func"](args)
696875
end

0 commit comments

Comments
 (0)