From 9eb145b5fd494e4479f2e1a7df47f1a4cddf54c8 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 Sep 2022 01:07:19 +0200 Subject: [PATCH 1/5] add autocomplete add small interface when scm is run directly without args --- README.md | 3 + scm.lua | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 186 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cd71808..f8217f4 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ Shows all installed scripts. Shows all available configurations. - ``: Shows the value of a specific configuration. - ` `: Updates the value of a specific configuration. +## refresh +Downloads the names of all programs and libraries of the official repository. +Refreshes autocomplete. ## help Shows all available commands and their description. - ``: Shows the description of a command by name. diff --git a/scm.lua b/scm.lua index 3a01f10..89ea125 100644 --- a/scm.lua +++ b/scm.lua @@ -12,6 +12,7 @@ scm.config = { ["programSuffix"] = "-prog", ["librarySuffix"] = "-lib", ["infoFile"] = "files.txt", -- provides the structure of a git repo (paths to all files) + ["apiGithubGetRepos"] = "https://api.github.com/orgs/mc-cc-scripts/repos?type=all&per_page=100&page=1", -- Local Settings ["installScript"] = "1kKZ8zTS", ["rootDirectory"] = "", @@ -24,7 +25,8 @@ scm.config = { ["printPrefix"] = "[scm] ", ["logDate"] = false, ["writeLogFile"] = false, - ["logFilePath"] = "logs/scm-log.txt" + ["logFilePath"] = "logs/scm-log.txt", + ["repoScriptsFile"] = "scm-repo-scripts.txt" -- will be saved in configDirectory as well } ---------------- @@ -130,6 +132,16 @@ $ config Updates the configuration ]] }, + ["refresh"] = { + func = function (args) + scm:refreshAutocomplete() + end, + description = [[ +$ refresh + Downloads the names of all programs and libraries of the official repository. + Refreshes autocomplete. + ]] + }, ["help"] = { ---@param args table func = function (args) @@ -152,6 +164,133 @@ $ help } } +function scm:refreshRepoScripts () + self:log("Downloading program and library names from GitHub...") + local repoScripts = {} + + local programs = {} + local libraries = {} + + local request = http.get(self.config["apiGithubGetRepos"]) + if request then + local response = request.readAll() + request.close() + + local responseTable = textutils.unserializeJSON(response) + for i = 1, #responseTable, 1 do + if string.sub(responseTable[i]["name"], -string.len(self.config["programSuffix"])) == self.config["programSuffix"] then + programs[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["programSuffix"]))] = {} + elseif string.sub(responseTable[i]["name"], -string.len(self.config["librarySuffix"])) == self.config["librarySuffix"] then + libraries[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["librarySuffix"]))] = {} + end + end + scm:log("Done") + else + scm:log("Download failed") + end + + self.commands["add"]["args"] = programs + self.commands["require"]["args"] = libraries + + repoScripts["libraries"] = libraries + repoScripts["programs"] = programs + + local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "w") + if file then + file.write(textutils.serializeJSON(repoScripts)) + file.close() + end +end + +function scm:loadRepoScripts () + local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "r") + + if not file then + self:refreshRepoScripts() + else + local repoScripts = textutils.unserializeJSON(file.readAll()) or nil + if repoScripts then + self.commands["add"]["args"] = repoScripts["programs"] + self.commands["require"]["args"] = repoScripts["libraries"] + end + + file.close() + end +end + +function scm:prepareAutocomplete () + -- prepare update and remove + scm:loadScripts() + local installedScripts = {} + for i = 1, #self.scripts, 1 do + installedScripts[self.scripts[i].name] = {} + end + installedScripts["all"] = {} + + self.commands["update"]["args"] = installedScripts + self.commands["remove"]["args"] = installedScripts + + -- prepare add and require + self:loadRepoScripts() + + -- prepare config + local availableConfigs = {} + + for k, _ in pairs(self.config) do + availableConfigs[k] = {} + end + + self.commands["config"]["args"] = availableConfigs + + -- prepare help + local availableCommands = {} + + for k, _ in pairs(self.commands) do + availableCommands[k] = {} + end + + self.commands["help"]["args"] = availableCommands +end + +---@param shell table +---@param index integer +---@param argument string +---@param previous table +---@return table | nil +local function completionFunction (shell, index, argument, previous) + local commands = {} + for k, _ in pairs(scm.commands) do + commands[k] = scm.commands[k]["args"] or {} + end + + local currArg = commands + for i = 2, #previous do + if currArg[previous[i]] then + currArg = currArg[previous[i]] + else + return nil + end + end + + local results = {} + for word, _ in pairs(currArg) do + if word:sub(1, #argument) == argument then + results[#results+1] = word:sub(#argument + 1) + end + end + return results; +end + +local function updateAutocomplete () + shell.setCompletionFunction("scm", completionFunction) +end + +function scm:refreshAutocomplete () + scm:refreshRepoScripts() + scm:prepareAutocomplete() + updateAutocomplete() +end + ---@param message string function scm:log (message) local datetime = "" @@ -392,7 +531,7 @@ function scm:addScript (sourceObject, success) if self.scripts[i].source[sourceObject.sourceName] then self.scripts[i].source[sourceObject.sourceName] = sourceObject.source[sourceObject.sourceName] self:saveScripts() - + return true end end @@ -400,13 +539,22 @@ function scm:addScript (sourceObject, success) if not scriptExists then scm:log("Script added: " .. sourceObject.name) - table.insert(self.scripts, sourceObject) + table.insert(self.scripts, sourceObject) else scm:log("Script already exists.") + return false end - + self:saveScripts() + -- update for autocomplete + self.commands["update"]["args"] = self.commands["update"]["args"] or {} + self.commands["remove"]["args"] = self.commands["remove"]["args"] or {} + self.commands["update"]["args"][sourceObject.name] = {} + self.commands["remove"]["args"][sourceObject.name] = {} + self:prepareAutocomplete() + updateAutocomplete() + return true end @@ -454,6 +602,7 @@ function scm:removeScript (name, keepScriptConfig) self:saveScripts() end + -- delete file if scriptType and fs.exists(self.config[scriptType .. "Directory"] .. name .. ".lua") then fs.delete(self.config[scriptType .. "Directory"] .. name .. self.config[scriptType .. "Suffix"]) if scriptType == "library" then @@ -464,6 +613,10 @@ function scm:removeScript (name, keepScriptConfig) if scriptType == "program" then fs.delete(name) end + + -- update autocomplete + self:prepareAutocomplete() + updateAutocomplete() end function scm:removeAllScripts () @@ -691,6 +844,32 @@ end ---@param args table function scm:handleArguments (args) + if #args == 0 then + -- enable autocomplete + self:prepareAutocomplete() + updateAutocomplete() + + -- some interface + local _, cursorY = term.getCursorPos() + term.setCursorPos(0, cursorY) + term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") + term.setCursorPos(0, cursorY) + term.scroll(1) + term.blit(" SCM - Script Manager ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") + term.setCursorPos(0, cursorY) + term.scroll(1) + term.blit(" Autocomplete enabled. ","777777777777777777777777777777777","444444444444444444444444444444444") + term.setCursorPos(0, cursorY) + term.scroll(1) + term.blit(" Type `scm help` to learn more. ","77777777ffffffff77777777777777777","444444444444444444444444444444444") + term.setCursorPos(0, cursorY) + term.scroll(1) + term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") + term.setCursorPos(0, cursorY) + term.scroll(2) + return + end + if args[1] and self.commands[args[1]] then self.commands[args[1]]["func"](args) end From bf9b54ea61d498d32a978a9b130ea55b588cf3e9 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 Sep 2022 19:21:33 +0200 Subject: [PATCH 2/5] fix positions add function to be used in startup.lua (scm:cli(true)) --- scm.lua | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/scm.lua b/scm.lua index 89ea125..d542e48 100644 --- a/scm.lua +++ b/scm.lua @@ -842,31 +842,40 @@ function scm:init () self:loadScripts() end +---@param resetPosition boolean | nil +function scm:cli (resetPosition) + if resetPosition ~= nil and resetPosition == true then + term.setCursorPos(1, 7) + end + + -- enable autocomplete + self:prepareAutocomplete() + updateAutocomplete() + + -- some interface + local _, cursorY = term.getCursorPos() + term.setCursorPos(1, cursorY) + term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444") + term.setCursorPos(1, cursorY) + term.scroll(1) + term.blit(" SCM - Script Manager ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444") + term.setCursorPos(1, cursorY) + term.scroll(1) + term.blit(" Autocomplete enabled. ","77777777777777777777777777777777","44444444444444444444444444444444") + term.setCursorPos(1, cursorY) + term.scroll(1) + term.blit(" Type `scm help` to learn more. ","77777777ffffffff7777777777777777","44444444444444444444444444444444") + term.setCursorPos(1, cursorY) + term.scroll(1) + term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444") + term.setCursorPos(1, cursorY) + term.scroll(2) +end + ---@param args table function scm:handleArguments (args) if #args == 0 then - -- enable autocomplete - self:prepareAutocomplete() - updateAutocomplete() - - -- some interface - local _, cursorY = term.getCursorPos() - term.setCursorPos(0, cursorY) - term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") - term.setCursorPos(0, cursorY) - term.scroll(1) - term.blit(" SCM - Script Manager ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") - term.setCursorPos(0, cursorY) - term.scroll(1) - term.blit(" Autocomplete enabled. ","777777777777777777777777777777777","444444444444444444444444444444444") - term.setCursorPos(0, cursorY) - term.scroll(1) - term.blit(" Type `scm help` to learn more. ","77777777ffffffff77777777777777777","444444444444444444444444444444444") - term.setCursorPos(0, cursorY) - term.scroll(1) - term.blit(" ","fffffffffffffffffffffffffffffffff","444444444444444444444444444444444") - term.setCursorPos(0, cursorY) - term.scroll(2) + self:cli() return end From 7907e3c00f6fb31c27c75c7a802424dce33e4a4b Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 Sep 2022 19:36:15 +0200 Subject: [PATCH 3/5] add `scm ` to console when run directly --- scm.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scm.lua b/scm.lua index d542e48..bff2fc9 100644 --- a/scm.lua +++ b/scm.lua @@ -843,7 +843,7 @@ function scm:init () end ---@param resetPosition boolean | nil -function scm:cli (resetPosition) +function scm:cli (resetPosition, args) if resetPosition ~= nil and resetPosition == true then term.setCursorPos(1, 7) end @@ -870,12 +870,16 @@ function scm:cli (resetPosition) term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444") term.setCursorPos(1, cursorY) term.scroll(2) + + if args and #args == 0 then + read(nil, nil, shell.complete, "scm ") + end end ---@param args table function scm:handleArguments (args) if #args == 0 then - self:cli() + self:cli(false, args) return end From b50f0bdb6d4a312fdaf3e4d682f4af24c5c624b1 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 Sep 2022 20:48:22 +0200 Subject: [PATCH 4/5] add option for cli prefix --- scm.lua | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scm.lua b/scm.lua index bff2fc9..b4c8d0a 100644 --- a/scm.lua +++ b/scm.lua @@ -26,7 +26,9 @@ scm.config = { ["logDate"] = false, ["writeLogFile"] = false, ["logFilePath"] = "logs/scm-log.txt", - ["repoScriptsFile"] = "scm-repo-scripts.txt" -- will be saved in configDirectory as well + ["repoScriptsFile"] = "scm-repo-scripts.txt", -- will be saved in configDirectory as well + ["allowCLIPrefix"] = true, + ["cliPrefix"] = false } ---------------- @@ -852,8 +854,15 @@ function scm:cli (resetPosition, args) self:prepareAutocomplete() updateAutocomplete() + -- enable newline starting with `scm ` + if self.config["allowCLIPrefix"] then + self.config["cliPrefix"] = true + self:saveConfig() + end + -- some interface local _, cursorY = term.getCursorPos() + if cursorY < 7 then cursorY = 7 end term.setCursorPos(1, cursorY) term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444") term.setCursorPos(1, cursorY) @@ -871,8 +880,8 @@ function scm:cli (resetPosition, args) term.setCursorPos(1, cursorY) term.scroll(2) - if args and #args == 0 then - read(nil, nil, shell.complete, "scm ") + if self.config["cliPrefix"] then + shell.run(read(nil, nil, shell.complete, "scm ")) end end @@ -885,6 +894,9 @@ function scm:handleArguments (args) if args[1] and self.commands[args[1]] then self.commands[args[1]]["func"](args) + if self.config["cliPrefix"] then + shell.run(read(nil, nil, shell.complete, "scm ")) + end end end From c2a63ae2e3e47bf9a9d2e7a824b73cc4821b2a78 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 8 Sep 2022 20:58:05 +0200 Subject: [PATCH 5/5] update for readability --- scm.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/scm.lua b/scm.lua index b4c8d0a..0f31229 100644 --- a/scm.lua +++ b/scm.lua @@ -179,11 +179,20 @@ function scm:refreshRepoScripts () request.close() local responseTable = textutils.unserializeJSON(response) + + local programSuffix = self.config["programSuffix"] + local librarySuffix = self.config["librarySuffix"] + for i = 1, #responseTable, 1 do - if string.sub(responseTable[i]["name"], -string.len(self.config["programSuffix"])) == self.config["programSuffix"] then - programs[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["programSuffix"]))] = {} - elseif string.sub(responseTable[i]["name"], -string.len(self.config["librarySuffix"])) == self.config["librarySuffix"] then - libraries[string.sub(responseTable[i]["name"], 0, string.len(responseTable[i]["name"])-string.len(self.config["librarySuffix"]))] = {} + local scriptName = responseTable[i]["name"] + if string.sub(scriptName, -string.len(programSuffix)) == programSuffix then + programs[ + string.sub(scriptName, 0, string.len(scriptName)-string.len(programSuffix)) + ] = {} + elseif string.sub(scriptName, -string.len(librarySuffix)) == librarySuffix then + libraries[ + string.sub(scriptName, 0, string.len(scriptName)-string.len(librarySuffix)) + ] = {} end end scm:log("Done")