Make shit less ass fuck shit fuck ass shit ass bruh what is this code

This commit is contained in:
2026-06-06 19:00:37 +03:00
parent 202f6d42ac
commit 4d6dbadc32
87 changed files with 1497 additions and 954 deletions
+5 -1
View File
@@ -1,3 +1,4 @@
local agregistry = {
["halyde"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
["edit"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
@@ -8,7 +9,10 @@ local agregistry = {
["hextra"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["utape"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["libctif"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["ctif-viewer"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/"
["ctif-viewer"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["libsha256"] = "https://raw.githubusercontent.com/tema5002/ag-packages/refs/heads/main/",
["sha256sum"] = "https://raw.githubusercontent.com/tema5002/ag-packages/refs/heads/main/",
["base64"] = "https://raw.githubusercontent.com/mcplayer3/AgPackages/refs/heads/main/"
}
return agregistry
+28 -28
View File
@@ -106,15 +106,15 @@ do
if parsed.flags.u or parsed.flags["update-registry"] then
terminal.write("Updating registry...")
result, data = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/ag2/registry.json")
check(result, "\27[91mFailed to get registry: " .. data)
check(result, "\27[91mFailed to get registry: " .. data .. "\27[0m")
local handle, errorMessage = fs.open("/ag2/registry.json", "w")
check(handle, "\27[91mFailed to open write handle to registry: " .. errorMessage)
check(handle, "\27[91mFailed to open write handle to registry: " .. errorMessage .. "\27[0m")
local success, errorMessage = handle:write(data)
check(success, "\27[91mFailed to write to registry: " .. errorMessage)
check(success, "\27[91mFailed to write to registry: " .. errorMessage .. "\27[0m")
handle:close()
else
result, data = getFile("/ag2/registry.json")
check(result, "\27[91mFailed to get registry: " .. data)
check(result, "\27[91mFailed to get registry: " .. data .. "\27[0m")
end
end
@@ -129,16 +129,16 @@ end
local function getServersidePackageConfig(source, package)
local success, data = getFile(fs.concat(source, "/ag2.json"))
if not success then
return false, ("\27[91mFailed to get package config (ag2.json) of package '%s': " .. data):format(package)
return false, ("\27[91mFailed to get package config (ag2.json) of package '%s': " .. data .. "\27[0m"):format(package)
end
local success, packageConfig = pcall(function()
return json.decode(data)
end)
if not success then
return false, ("\27[91mFailed to parse package config (ag2.json) of package '%s': " .. packageConfig):format(package)
return false, ("\27[91mFailed to parse package config (ag2.json) of package '%s': " .. packageConfig .. "\27[0m"):format(package)
end
if not packageConfig[package] then
return false, ("\27[91mRepository package config (ag2.json) does not contain package '%s'."):format(package)
return false, ("\27[91mRepository package config (ag2.json) does not contain package '%s'.\27[0m"):format(package)
end
return packageConfig[package]
end
@@ -158,7 +158,7 @@ if command == "install" then
table.remove(otherPackages, i)
-- This is to check if the package can be found in the others, or in other words, checking for duplicates
if table.find(otherPackages, packages[i]) then
print(("\27[93mDuplicate package specified (%s), skipping"):format(packages[i]))
print(("\27[93mDuplicate package specified (%s), skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
@@ -170,7 +170,7 @@ if command == "install" then
source = registry[packages[i]]
end
if not source then
print("\27[91mCould not find package in registry and no source provided: " .. packages[i])
print("\27[91mCould not find package in registry and no source provided: " .. packages[i] .. "\27[0m")
failure = true
goto SKIP
end
@@ -212,7 +212,7 @@ if command == "install" then
goto SKIP
end
if fs.exists(("/ag2/pkg/%s.json"):format(packages[i])) then
print(("\27[93mPackage %s is already installed, skipping"):format(packages[i]))
print(("\27[93mPackage %s is already installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
@@ -248,7 +248,7 @@ elseif command == "remove" then
end
end
end
print(("\27[93mPackage %s is not installed, skipping"):format(packages[i]))
print(("\27[93mPackage %s is not installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
::GOAHEAD::
@@ -299,7 +299,7 @@ elseif command == "remove" then
-- Listen, I'm so sorry for this abhorrent bullshit code, but the newly added packages have to get checked one way or another and hopefully this is readable enough.
else
-- The Pyramids of Giza were built entirely out of silver. No they weren't...
print(("\27[93mPackage %s is depended on by %s, cannot uninstall without --cascade"):format(dependency, packageName))
print(("\27[93mPackage %s is depended on by %s, cannot uninstall without --cascade\27[0m"):format(dependency, packageName))
failure = true
end
end
@@ -324,9 +324,9 @@ end
if command == "install" then
if dependencyCounter == 1 then
print("\27[93m1 dependency pulled in.")
print("\27[93m1 dependency pulled in.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d dependencies pulled in."):format(dependencyCounter))
print(("\27[93m%d dependencies pulled in.\27[0m"):format(dependencyCounter))
end
print("Packages that will be installed:")
print(table.concat(packages, ", "))
@@ -359,13 +359,13 @@ if command == "install" then
local success, data = getFile(fs.concat(source, file))
if not success then
print(("\27[91mFailed to get file '%s' of package '%s': " .. data):format(file, package))
print(("\27[91mFailed to get file '%s' of package '%s': " .. data .. "\27[0m"):format(file, package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s."):format(file))
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
@@ -373,26 +373,26 @@ if command == "install" then
end
if fs.exists(file) then
print(("\27[93mFile '%s' already exists."):format(file))
print(("\27[93mFile '%s' already exists.\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Overwrite, Skip? [a/O/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s."):format(file))
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
end
end
local handle, errorMessage = fs.open(file, "w")
if not handle then
print(("\27[91mFailed to open write handle to file '%s': " .. errorMessage):format(file))
print(("\27[91mFailed to open write handle to file '%s': " .. errorMessage .. "\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s."):format(file))
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
@@ -402,13 +402,13 @@ if command == "install" then
local success, errorMessage = handle:write(data)
if not success then
handle:close()
print(("\27[91mFailed to write to file '%s': " .. errorMessage):format(file))
print(("\27[91mFailed to write to file '%s': " .. errorMessage .. "\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s."):format(file))
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
@@ -431,13 +431,13 @@ if command == "install" then
::RETRY::
local handle, errorMessage = fs.open(("/ag2/pkg/%s.json"):format(package), "w")
if not handle then
print(("\27[91mFailed to open write handle to file '/ag2/pkg/%s.json': " .. errorMessage):format(package))
print(("\27[91mFailed to open write handle to file '/ag2/pkg/%s.json': " .. errorMessage .. "\27[0m"):format(package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file /ag2/pkg/%s.json."):format(package))
print((" \27[93mSkipped file /ag2/pkg/%s.json.\27[0m"):format(package))
goto SKIP
else
goto RETRY
@@ -461,13 +461,13 @@ if command == "install" then
local success, errorMessage = handle:write(trackingFile)
if not success then
handle:close()
print(("\27[91mFailed to write to file '/ag2/pkg/%s.json': " .. errorMessage):format(package))
print(("\27[91mFailed to write to file '/ag2/pkg/%s.json': " .. errorMessage .. "\27[0m"):format(package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file /ag2/pkg/%s.json."):format(package))
print((" \27[93mSkipped file /ag2/pkg/%s.json.\27[0m"):format(package))
goto SKIP
else
goto RETRY
@@ -479,9 +479,9 @@ if command == "install" then
end
elseif command == "remove" then
if dependencyCounter == 1 then
print("\27[93m1 orphaned dependency will be removed.")
print("\27[93m1 orphaned dependency will be removed.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d orphaned dependencies will be removed."):format(dependencyCounter))
print(("\27[93m%d orphaned dependencies will be removed.\27[0m"):format(dependencyCounter))
end
print("Packages that will be removed:")
print(table.concat(packages, ", "))
+28 -31
View File
@@ -9,7 +9,7 @@ if not command then
return
end
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.")
print("\27[91mThis program requires an internet card to run.\27[0m")
return
end
local internet = component.internet
@@ -69,12 +69,12 @@ local function getAgConfig(package, source)
source = source or agReg[package]
local data, errorMessage = getFile(source .. "argentum.cfg")
if not data or data == "" then
print("\27[91mCould not fetch Ag config: " .. (errorMessage or "returned nil data"))
print("\27[91mCould not fetch Ag config: " .. (errorMessage or "returned nil data") .. "\27[0m")
return false
end
local func, errorMessage = load(data, "=argentum.cfg", "bt", {})
if not func then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.\27[0m")
return false
end
local agcfg
@@ -82,22 +82,22 @@ local function getAgConfig(package, source)
agcfg = func()
end)
if not status then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.\27[0m")
return false
end
if not agcfg[package] or not agcfg[package].maindir or not agcfg[package].directories or not agcfg[package].files or not agcfg[package].version then
local response = ("\27[91mAg config of " .. package .. " is improperly configured.\nPlease contact the package owner.")
local response = "\27[91mAg config of " .. package .. " is improperly configured.\nPlease contact the package owner.\27[0m"
end
return agcfg
end
local function doChecks(package)
if not agReg[package] and not source then
print("\27[91mPackage " .. package .. " does not exist.")
print("\27[91mPackage " .. package .. " does not exist.\27[0m")
return false
end
if fs.exists("/argentum/store/" .. package) then
print("\27[91mPackage " .. package .. " is already installed.")
print("\27[91mPackage " .. package .. " is already installed.\27[0m")
return false
end
agcfg = getAgConfig(package, source)
@@ -107,7 +107,7 @@ local function doChecks(package)
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]"})
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]\27[0m"})
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
@@ -132,24 +132,21 @@ local function lpad(str, len, char)
return string.rep(char, len - #str) .. str
end
local gpu = component.gpu
local width,height = gpu.getResolution()
local function progress(package,progress)
local info = string.format("%s %s%%",package,lpad(math.floor(progress*100),2))
local width, height = terminal.getResolution()
local function progress(package, progress)
terminal.write("\x1b[s")
local info = string.format("%s %s%%", package, lpad(math.floor(progress * 100), 2))
info = info .. string.rep(" ", width - #info)
local progX = math.floor(progress * width)
gpu.setBackground(0x00FF00)
gpu.setForeground(0x000000)
gpu.set(1,height,info:sub(1,progX))
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.set(progX+1,height,info:sub(progX+1))
terminal.write("\x1b[42m\x1b[30m" .. info:sub(1, progX) .. "\x1b[40m\x1b[37m" .. info:sub(progX + 1) .. "\x1b[0m")
terminal.write("\x1b[u")
end
local function clearProgress()
gpu.setBackground(0x000000)
gpu.fill(1,height,width,1," ")
terminal.write("\x1b[s")
terminal.write("\r\x1b[40m" .. string.rep(" ", width) .. "\x1b[0m\r")
terminal.write("\x1b[u")
end
local function installPackage(package, overwriteFlag)
@@ -166,7 +163,7 @@ local function installPackage(package, overwriteFlag)
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]"})
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]\27[0m"})
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
@@ -218,7 +215,7 @@ local function installPackage(package, overwriteFlag)
else
packageStore = packageStore .. "\nA" .. file
end
local handle = fs.open(file, "w")
local handle, err = fs.open(file, "w")
handle:write(data)
handle:close()
::skip::
@@ -234,7 +231,7 @@ end
local function removePackage(package)
print("Removing " .. package .. "...")
if not fs.exists("/argentum/store/" .. package .. "/package.cfg") then
print("\27[91mLocal Ag config of " .. package .. " does not exist.")
print("\27[91mLocal Ag config of " .. package .. " does not exist.\27[0m")
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
@@ -344,7 +341,7 @@ if command == "install" then
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
while true do
@@ -402,19 +399,19 @@ elseif command == "remove" then
end
while true do
if not fs.exists("/argentum/store/" .. packages[i]) then
print("\27[91mPackage " .. packages[i] .. " is not installed.")
print("\27[91mPackage " .. packages[i] .. " is not installed.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "halyde" then -- yes, this stuff is hard-coded.
print("\27[91mFor obvious reasons, you can't uninstall Halyde.")
print("\27[91mFor obvious reasons, you can't uninstall Halyde.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "argentum" then
print("\27[91mFor obvious reasons, you can't uninstall Argentum.")
print("\27[91mFor obvious reasons, you can't uninstall Argentum.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
@@ -495,7 +492,7 @@ elseif command == "update" then
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
if not packages[1] then
@@ -541,7 +538,7 @@ elseif command == "update" then
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
else
print(packages[i].." is out of date [\x1b[93m"..version.."\x1b[39m < \x1b[92m"..agcfg[packages[i]].version.."\x1b[39m]")
print(packages[i].." is out of date [\x1b[93m"..version.."\x1b[0m < \x1b[92m"..agcfg[packages[i]].version.."\x1b[0m")
end
end
i = i + 1
@@ -630,7 +627,7 @@ elseif command == "info" then
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
if not agReg[packages[1]] and not source then
@@ -677,7 +674,7 @@ elseif command == "list" then
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
local sortedPackages = {}
+1 -1
View File
@@ -9,7 +9,7 @@ cliparse.config({
})
local parsed, err = cliparse.parse(...)
if not parsed then
return print("\x1b[91m" .. err)
return print("\x1b[91m" .. err .. "\x1b[0m")
end
local freq =
+5 -5
View File
@@ -34,25 +34,25 @@ if type(args[1])=="string" then
local compID,err = getComponentID(args[1])
if not compID then
print("\x1b[91mCould not get component ID from '"..args[1].."'.")
if type(err)=="string" then print("\x1b[91m"..err) end
if type(err)=="string" then print("\x1b[91m"..err.."\x1b[0m") end
return
end
if not force then
if component.virtual.check(compID) then
return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..compID)
return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..compID.."\x1b[0m")
end
local type = component.type(compID)
if type~="filesystem" and type~="drive" then
return print("\x1b[91mThis component is not a storage medium.\nID: "..compID)
return print("\x1b[91mThis component is not a storage medium.\nID: "..compID.."\x1b[0m")
end
if type=="filesystem" and not fileExists(compID,"/init.lua") then
return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..compID)
return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..compID.."\x1b[0m")
end
end
computer.setBootAddress(compID)
if computer.getBootAddress()~=compID then
return print("\x1b[91mFailed to set the boot address.")
return print("\x1b[91mFailed to set the boot address.\x1b[0m")
end
computer.shutdown(true)
else
+20 -16
View File
@@ -1,21 +1,25 @@
local files = { ... }
local shell = require("shell")
local fs = require("filesystem")
if not files or not files[1] then
shell.run("help cat")
return
end
for _, file in ipairs(files) do
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.getWorkingDirectory(), file)
end
if not fs.exists(file) then
print("\27[91mFile does not exist.")
local shell = require("shell")
local args = {...}
if not args[1] then
return shell.run("help cat")
end
for _, file in pairs(args) do
file = shell.resolvePath(file)
local handle = fs.open(file, "r")
local data
repeat
data = handle:read(math.huge or math.maxinteger)
if handle == nil then
terminal.write("\27[91mCan't open " .. file .. "\27[0m\n")
goto continue
end
while true do
local data = handle:read(math.huge or math.maxinteger)
if data == nil then break end
terminal.write(data)
until not data
end
handle:close()
::continue::
end
+19 -8
View File
@@ -1,15 +1,26 @@
local directory = ...
local args = {...}
if args[2] then
terminal.write("\27[91mToo many arguments.\27[0m")
end
if not args[1] then
return
end
local fs = require("filesystem")
local shell = require("shell")
if not directory then
local directory = shell.resolvePath(args[1])
if not fs.exists(directory) then
terminal.write("\27[91mError: " .. directory .. ": No such file or directory\27[0m\n")
return
end
if directory:sub(1, 1) ~= "/" then
directory = fs.concat(shell.getWorkingDirectory(), directory)
if not fs.isDirectory(directory) then
terminal.write("\27[91mError: " .. directory .. ": Not a directory\27[0m\n")
return
end
if fs.exists(directory) and fs.isDirectory(directory) then
shell.setWorkingDirectory(fs.canonical(directory))
else
print("\27[91mNo such directory.")
end
+1
View File
@@ -1,2 +1,3 @@
terminal.clear()
-- truly so much going on here
-- meow
+59 -16
View File
@@ -1,27 +1,70 @@
local fromFile, toFile = ...
local fs = require("filesystem")
local shell = require("shell")
if not fromFile or not toFile then
shell.run("help cp")
local args = {...}
if not args[1] then
return shell.run("help cp")
end
if not args[2] then
terminal.write("\27[91mError: No destination\27[0m\n")
return
end
if fromFile:sub(1, 1) ~= "/" then
fromFile = fs.concat(shell.getWorkingDirectory(), fromFile)
end
if toFile:sub(1, 1) ~= "/" then
toFile = fs.concat(shell.getWorkingDirectory(), toFile)
end
if fromFile == toFile then
print("\27[91mSource and destination are the same.")
local dest = shell.resolvePath(args[#args])
if fs.isFile(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: Destination is not a directory\27[0m\n")
return
end
if not fs.exists(fromFile) then
print("\27[91mSource file does not exist.")
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
if fs.exists(toFile) and not (table.find({...}, "-o") or table.find({...}, "--overwrite")) then
print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")
if fs.isDirectory(src) then
terminal.write("\27[91mError: Cannot write directory " .. src .. " to file " .. dest .. "\27[0m\n")
return
end
fs.copy(fromFile, toFile)
fs.copy(src, dest)
elseif fs.isDirectory(dest) then
for i = 1, #args - 1 do
local src = shell.resolvePath(args[i])
if src == dest then
terminal.write("\27[91mError: Source and destination are the same\27[0m\n")
goto continue
end
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
goto continue
end
fs.copy(src, fs.concat(dest, fs.basename(src)))
::continue::
end
elseif not fs.exists(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: " .. dest .. ": No such file or directory\27[0m\n")
return
end
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
local destp = fs.parent(dest)
if not fs.exists(destp) then
terminal.write("\27[91mError: " .. destp .. ": No such file or directory\27[0m\n")
return
end
if not fs.isDirectory(destp) then
terminal.write("\27[91mError: " .. destp .. ": Not a directory\27[0m\n")
return
end
fs.copy(src, dest)
else
terminal.write("\27[91mUnknown error\27[0m\n")
end
+5 -5
View File
@@ -4,7 +4,7 @@ local component = require("component")
local fs = require("filesystem")
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.")
print("\27[91mThis program requires an internet card to run.\27[0m")
return
end
@@ -26,11 +26,11 @@ local status, errorMessage = pcall(function()
request:finishConnect()
end)
if not status then
print("\27[91mDownload failed: " .. errorMessage)
print("\27[91mDownload failed: " .. errorMessage .. "\27[0m")
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
print("\27[91mDownload failed: " .. tostring(responseCode))
print("\27[91mDownload failed: " .. tostring(responseCode) .. "\27[0m")
end
repeat
tmpdata = request.read(math.huge)
@@ -41,9 +41,9 @@ local saveLocationOK = false
repeat
saveLocation = terminal.read(nil, "File save location: ", fs.concat(require("shell").getWorkingDirectory(), url:match("/([^/]+)$")))
if fs.isDirectory(saveLocation) then
print("\27[91mThe specified location is a directory.")
print("\27[91mThe specified location is a directory.\27[0m")
elseif fs.exists(saveLocation) then
local answer = terminal.read({prefix = "\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]"})
local answer = terminal.read({prefix = "\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]\27[0m"})
if answer:lower() ~= "n" then
saveLocationOK = true
end
+3 -4
View File
@@ -16,8 +16,7 @@ local tab = " "
--local ocelot = component.ocelot
local function rawset(x, y, text)
terminal.setCursorPos(x,y)
terminal.write(text, false)
terminal.write("\x1b[".. tostring(y) .. ";" .. tostring(x) .. "H" .. text)
end
local filestring, filepath, handle, data, tmpdata
@@ -261,7 +260,7 @@ local function save()
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, string.rep(" ", width))
terminal.setCursorPos(1, height - 1)
rawset(1, height - 1)
local savepath = terminal.read({prefix = "\27[107m\27[30mSave location: ", defaultText = filepath})
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
@@ -300,7 +299,7 @@ while true do
renderFlag, cursorRenderFlag, specialKey = processEvent(args)
if specialKey == "x" then
if changesMade then
terminal.setCursorPos(1, height - 1)
rawset(1, height - 1)
local response = terminal.read({prefix = "\27[107m\27[30mWould you like to save changes? [Y/n] "})
if response:lower() ~= "n" then
save()
+36 -53
View File
@@ -2,82 +2,65 @@ local component = require("component")
local computer = require("computer")
local filesystem = require("filesystem")
local function convert(value, fromUnit, toUnit)
local units = {B = 1, KiB = 1024, MiB = 1024^2, GiB = 1024^3}
return value * units[fromUnit] / units[toUnit]
end
local function printstat(text)
local cursorPosX, cursorPosY = terminal.getCursorPos()
terminal.setCursorPos(35, cursorPosY)
terminal.write(text .. "\n", false)
terminal.write("\27[35G" .. text .. "\n")
end
local logo = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
tmpdata = handle:read(math.inf or math.maxinteger)
tmpdata = handle:read(math.huge)
logo = logo .. (tmpdata or "")
until not tmpdata
handle:close()
terminal.write(logo)
terminal.write("\27[17A")
terminal.write(logo, false)
local cursorPosX, cursorPosY = terminal.getCursorPos()
terminal.setCursorPos(cursorPosX, cursorPosY - 17)
printstat("\27[92mOS\27[0m: " .. _OSVERSION)
printstat("\27[92mArchitecture\27[0m: " .. _VERSION)
local componentCounter = 0
for _, _ in component.list() do
for _ in component.list() do
componentCounter = componentCounter + 1
end
printstat("\27[92mComponents\27[0m: " .. tostring(componentCounter))
printstat("\27[92mCoroutines\27[0m: " .. tostring(#tsched.getTasks()))
printstat(
"\27[92mBattery\27[0m: " .. tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10) .. "%"
)
printstat("\27[92mBattery\27[0m: " .. tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10) .. "%")
local totalMemory = computer.totalMemory()
local usedMemory = computer.totalMemory() - computer.freeMemory()
local totalMemoryString
if convert(totalMemory, "B", "GiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(totalMemory, "B", "MiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(totalMemory, "B", "KiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
local function formatBytes(bytes)
if convert(bytes, "B", "GiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(bytes, "B", "MiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(bytes, "B", "KiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
totalMemoryString = tostring(totalMemory) .. " B"
return tostring(bytes) .. " B"
end
local usedMemoryString
if convert(usedMemory, "B", "GiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(usedMemory, "B", "MiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(usedMemory, "B", "KiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
usedMemoryString = tostring(usedMemory) .. " B"
end
printstat("\27[92mMemory\27[0m: " .. usedMemoryString .. " / " .. totalMemoryString)
printstat("\27[92mMemory\27[0m: " .. formatBytes(usedMemory) .. " / " .. formatBytes(totalMemory))
local totalDisk = component.invoke(computer.getBootAddress(), "spaceTotal")
local usedDisk = component.invoke(computer.getBootAddress(), "spaceUsed")
local totalDiskString
if convert(totalDisk, "B", "GiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(totalDisk, "B", "MiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(totalDisk, "B", "KiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
totalDiskString = tostring(totalDisk) .. " B"
end
local usedDiskString
if convert(usedDisk, "B", "GiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(usedDisk, "B", "MiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(usedDisk, "B", "KiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
usedDiskString = tostring(usedDisk) .. " B"
end
printstat("\27[92mDisk\27[0m: " .. usedDiskString .. " / " .. totalDiskString)
local width, height = component.invoke(component.list("gpu")(), "getResolution")
printstat("\27[92mDisk\27[0m: " .. formatBytes(usedDisk) .. " / " .. formatBytes(totalDisk))
local gpuComponent = component.list("gpu")()
local width, height = component.invoke(gpuComponent, "getResolution")
printstat("\27[92mResolution\27[0m: " .. tostring(width) .. "x" .. tostring(height) .. "\n")
printstat("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")
printstat("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")
local cursorPosX, cursorPosY = terminal.getCursorPos()
terminal.setCursorPos(cursorPosX, cursorPosY + 5)
terminal.write("\27[5B\27[0m")
+260 -32
View File
@@ -1,40 +1,268 @@
local shell = require("shell")
local fs = require("filesystem")
local args = {...}
local command = args[1]
args = nil
if not command then
local handle, data, tmpdata = fs.open("/halyde/apps/helpdb/default.txt", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
print(data)
local shell = require("shell")
local arg = ... or "default"
local what = arg
local aliases = shell.getAliases()
if aliases[what] then
what = aliases[what]
end
local path = "/halyde/apps/helpdb/" .. what
if not fs.exists(path) then
print("Could not find help file for: " .. arg .. ".")
return
end
local aliases = shell.getAliases()
if aliases[command] then
command = aliases[command]
if path == "/halyde/apps/helpdb/default" then
return shell.run("cat " .. path) -- smh
end
if fs.exists("/halyde/apps/helpdb/" .. command .. ".txt") then
local handle, data, tmpdata = fs.open("/halyde/apps/helpdb/" .. command .. ".txt", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
print(data)
-- local aliases = table.copy(shell.aliases)
if table.find(aliases, command) then
local aliasIndex = table.find(aliases, command)
local aliasString = "Aliases:\n " .. aliasIndex
aliases[aliasIndex] = nil
while table.find(aliases, command) do
aliasIndex = table.find(aliases, command)
aliasString = aliasString .. ", " .. aliasIndex
aliases[aliasIndex] = nil
local handle = fs.open(path, "r")
local data = {
command = "",
usage = "",
description = "",
args = {},
examples = {}
}
while true do
local line = ""
while true do
local char = handle:read(1)
if not char then
if line == "" then
line = nil
break
end
print(aliasString)
break
end
if char == "\n" then
break
end
if char == "\r" then
local next_char = handle:read(1)
if next_char and next_char == "\n" then
break
elseif next_char then
local pos = file:seek("cur")
if pos then
file:seek("set", pos - 1)
end
break
end
break
end
line = line .. char
end
if line == nil then
break
end
line = line:match("^%s*(.-)%s*$")
if line then
local key, value = line:match("^(%w+)%s+(.*)$")
if not key then goto continue end
if key:lower() == "command" then
data.command = value
end
if key:lower() == "usage" then
data.usage = value
end
if key:lower() == "description" then
data.description = value
end
if key:lower():match("^arg%d+$") then
local num = key:lower():match("^arg(%d+)$")
if not data.args[tonumber(num)] then data.args[tonumber(num)] = {} end
data.args[tonumber(num)].name = value
end
if key:lower():match("^arg%d+description$") then
local num = key:lower():match("^arg(%d+)description$")
if not data.args[tonumber(num)] then data.args[tonumber(num)] = {} end
data.args[tonumber(num)].description = value
end
if key:lower():match("^arg%d+sub%d+$") then
local main_num, sub_num = key:lower():match("^arg(%d+)sub(%d+)$")
if main_num and sub_num then
if not data.args[tonumber(main_num)] then data.args[tonumber(main_num)] = {} end
if not data.args[tonumber(main_num)].subflags then data.args[tonumber(main_num)].subflags = {} end
if not data.args[tonumber(main_num)].subflags[tonumber(sub_num)] then
data.args[tonumber(main_num)].subflags[tonumber(sub_num)] = {}
end
data.args[tonumber(main_num)].subflags[tonumber(sub_num)].name = value
end
end
if key:lower():match("^arg%d+sub%d+description$") then
local main_num, sub_num = key:lower():match("^arg(%d+)sub(%d+)description$")
if main_num and sub_num then
if not data.args[tonumber(main_num)] then data.args[tonumber(main_num)] = {} end
if not data.args[tonumber(main_num)].subflags then data.args[tonumber(main_num)].subflags = {} end
if not data.args[tonumber(main_num)].subflags[tonumber(sub_num)] then
data.args[tonumber(main_num)].subflags[tonumber(sub_num)] = {}
end
data.args[tonumber(main_num)].subflags[tonumber(sub_num)].description = value
end
end
if key:lower():match("^example%d+$") then
local num = key:lower():match("^example(%d+)$")
if not data.examples[tonumber(num)] then data.examples[tonumber(num)] = {} end
data.examples[tonumber(num)].name = value
end
if key:lower():match("^example%d+description$") then
local num = key:lower():match("^example(%d+)description$")
if not data.examples[tonumber(num)] then data.examples[tonumber(num)] = {} end
data.examples[tonumber(num)].description = value
end
::continue::
end
end
handle:close()
--print(require("serialize")(data, "\t"))
-- Halyde terminal doesn't support bold (CSI 1 m) but who cares
if data.command then
terminal.write("\27[1mUsage: \27[0m\n")
terminal.write(" \27[96m" .. data.command)
if data.usage then
terminal.write("\27[93m " .. data.usage)
end
terminal.write("\27[0m\n\n")
end
local width, height = terminal.getResolution()
local function wrap_text(text, indent)
if not text then return "" end
local words = {}
for word in text:gmatch("%S+") do
table.insert(words, word)
end
local lines = {}
local current_line = ""
for i, word in ipairs(words) do
if #current_line + #word + 1 <= width * 0.66 - indent then
if current_line == "" then
current_line = word
else
current_line = current_line .. " " .. word
end
else
print("Could not find help file for: " .. command .. ".")
table.insert(lines, current_line)
current_line = word
end
end
if current_line ~= "" then
table.insert(lines, current_line)
end
local result = {}
for i, line in ipairs(lines) do
if i == 1 then
table.insert(result, line)
else
table.insert(result, string.rep(" ", indent) .. line)
end
end
return table.concat(result, "\n")
end
if data.description then
terminal.write("\27[1mDescription:\27[0m\n")
terminal.write(" " .. wrap_text(data.description, 2))
terminal.write("\n\n")
end
if #data.args > 0 then
terminal.write("\27[1mArguments:\27[0m\n")
local max_len = 0
for _, flag in ipairs(data.args) do
if flag.name then
max_len = math.max(max_len, #flag.name)
end
for _, subf in ipairs(flag.subflags or {}) do
if subf.name then
max_len = math.max(max_len, #subf.name + 2)
end
end
end
for _, flag in ipairs(data.args) do
terminal.write(" \27[93m" .. (flag.name or "") .. "\27[0m" .. string.rep(" ", max_len - (flag.name and #flag.name or 0) + 2) .. wrap_text(flag.description, 4 + max_len) .. "\n")
for _, subf in ipairs(flag.subflags or {}) do
terminal.write(" \27[92m" .. (subf.name or "") .. "\27[0m" .. string.rep(" ", max_len - (subf.name and #subf.name or 0)) .. wrap_text(subf.description, 4 + max_len) .. "\n")
end
end
terminal.write("\n")
end
local function formatExampleName(name, utility)
if not name then return name end
local contains = false
if name:find(utility, 1, true) then
contains = true
else
for alias, cmd in pairs(aliases) do
if cmd == utility and name:find(alias, 1, true) then
contains = true
break
end
end
end
if not contains then
return "\27[92m" .. name
end
local formatted = name
formatted = formatted:gsub("(" .. utility .. ")", "\27[96m%1\27[92m")
for alias, cmd in pairs(aliases) do
if cmd == utility then
formatted = formatted:gsub("(" .. alias .. ")", "\27[96m%1\27[92m")
end
end
return formatted
end
if #data.examples > 0 then
terminal.write("\27[1mExamples:\27[0m\n")
local max_len = 0
for _, flag in ipairs(data.examples) do
max_len = math.max(max_len, #flag.name)
end
for _, flag in ipairs(data.examples) do
terminal.write(" " .. formatExampleName(flag.name, arg) .. "\27[0m" .. string.rep(" ", max_len - #flag.name + 2) .. wrap_text(flag.description, 4 + max_len) .. "\n")
end
terminal.write("\n")
end
local first = true
for k, v in pairs(aliases) do
if v == arg then
if first then
terminal.write("\27[1mAliases:\27[0m\n ")
end
terminal.write("\27[96m" .. k)
if not first then
terminal.write("\27[0m, ")
end
first = false
end
end
if not first then
terminal.writec(0xa)
end
+47
View File
@@ -0,0 +1,47 @@
COMMAND ag2
USAGE [COMMAND] [PACKAGES] [FLAGS]
DESCRIPTION Uses the Argentum 2 package manager.
ARG1 COMMAND
ARG1SUB1 install
ARG1SUB2 remove
ARG1SUB3 update
ARG1SUB4 list
ARG1SUB5 repo-list
ARG1SUB6 repo-add
ARG1SUB7 repo-remove
ARG1SUB8 info
ARG2 PACKAGES
ARG3 FLAGS
ARG3SUB1 -x, --exclude-deps
ARG3SUB2 -u, --update-repos
ARG3SUB3 -f, --force
ARG3SUB4 -c, --clean
ARG3SUB5 -s, --source [URL]
ARG3SUB6 -C, --cascade
ARG1DESCRIPTION Specifies the operation for Argentum 2 to do.
ARG1SUB1DESCRIPTION Installs packages.
ARG1SUB2DESCRIPTION Removes packages.
ARG1SUB3DESCRIPTION Updates packages.
ARG1SUB4DESCRIPTION Lists all available packages.
ARG1SUB5DESCRIPTION Lists all installed repositories.
ARG1SUB6DESCRIPTION Adds a custom repository.
ARG1SUB7DESCRIPTION Removes a repository.
ARG1SUB8DESCRIPTION Shows a packages version, description and other relevant information.
ARG2DESCRIPTION Packages to apply operations to.
ARG3DESCRIPTION These flags are available and can be inserted anywhere
ARG3SUB1DESCRIPTION Ignore dependencies. WARNING: Using this can and will leave you with broken packages. Use it at your own risk and only when truly necessary.
ARG3SUB2DESCRIPTION Update the list of repositories.
ARG3SUB3DESCRIPTION Force the operation, even if there are conflicts or unresolvable dependencies. WARNING: Using this can and will leave you with broken packages. Use it at your own risk and only when truly necessary.
ARG3SUB4DESCRIPTION Clean up now-unnecessary packages (previous dependencies).
ARG3SUB5DESCRIPTION Use a custom source for the operation.
ARG3SUB6DESCRIPTION When removing a package that other packages depend on, remove those packages too instead of aborting.
EXAMPLE1 ag2 install halyde
EXAMPLE2 ag2 list
EXAMPLE3 ag2 info halyde
EXAMPLE4 ag2 remove -x edit
EXAMPLE5 ag2 remove -c hal-draw
EXAMPLE1DESCRIPTION Installs the halyde package.
EXAMPLE2DESCRIPTION Lists all packages.
EXAMPLE3DESCRIPTION Shows information about the halyde package.
EXAMPLE4DESCRIPTION Removes edit, but does not remove any packages that depend on it.
EXAMPLE5DESCRIPTION Removes hal-draw and any dependencies that are no longer needed.
-32
View File
@@ -1,32 +0,0 @@
Usage: ag2 [COMMAND] [PACKAGES]
Uses the Argentum 2 package manager.
COMMAND Specifies the operation for Argentum 2 to do.
install Installs packages.
remove Removes packages.
update Updates packages.
list Lists all available packages.
repo-list Lists all installed repositories.
repo-add Adds a custom repository.
repo-remove Removes a repository.
info Shows a packages version, description and other relevant information.
PACKAGES* Packages to work on.
These flags are also available and can be inserted anywhere:
-x, --exclude-deps Ignore dependencies.
WARNING: Using this can and will leave you with broken packages.
Use it at your own risk and only when truly necessary.
-u, --update-repos Update the list of repositories.
-f, --force Force the operation, even if there are conflicts or unresolvable dependencies.
WARNING: Using this can and will leave you with broken packages.
Use it at your own risk and only when truly necessary.
-c, --clean Clean up now-unnecessary packages (previous dependencies).
-s, --source [URL] Use a custom source for the operation.
-C, --cascade When removing a package that other packages depend on, remove those packages too instead of aborting.
Examples:
ag2 install halyde Installs the halyde package.
ag2 list Lists all packages.
ag2 info halyde Shows information about the halyde package.
ag2 remove -x edit Removes edit, but does not remove any packages that depend on it.
ag2 remove -c hal-draw Removes hal-draw and any dependencies that are no longer needed.
+29
View File
@@ -0,0 +1,29 @@
COMMAND argentum
USAGE [COMMAND] [PACKAGES]
DESCRIPTION Uses the Argentum package manager.
ARG1 COMMAND
ARG1SUB1 install
ARG1SUB2 remove
ARG1SUB3 update
ARG1SUB4 list
ARG1SUB5 search
ARG1SUB6 info
ARG2 PACKAGES
ARG1DESCRIPTION Specifies the operation for Ag to do.
ARG1SUB1DESCRIPTION Installs packages.
ARG1SUB2DESCRIPTION Removes packages.
ARG1SUB3DESCRIPTION Updates packages.
ARG1SUB4DESCRIPTION Lists all available packages.
ARG1SUB5DESCRIPTION Searches all available packages.
ARG1SUB6DESCRIPTION Shows information on a specific package.
ARG2DESCRIPTION Packages to apply operations to.
EXAMPLE1 ag install hal-draw
EXAMPLE2 ag list
EXAMPLE3 ag info hal-draw
EXAMPLE4 ag update hal-draw
EXAMPLE5 ag update hal-draw
EXAMPLE1DESCRIPTION Installs the hal-draw package.
EXAMPLE2DESCRIPTION Lists all packages.
EXAMPLE3DESCRIPTION Shows information about hal-draw.
EXAMPLE4DESCRIPTION Updates the hal-draw package if it's not at the newest version.
EXAMPLE5DESCRIPTION Updates all packages.
-18
View File
@@ -1,18 +0,0 @@
Usage: argentum [COMMAND] [PACKAGES]
Uses the Argentum package manager.
COMMAND Specifies the operation for Ag to do.
install Installs packages.
remove Removes packages.
update Updates packages.
list Lists all available packages.
search Searches all available packages.
info Shows information on a specific package.
PACKAGES* Packages to apply operations to.
Examples:
ag install hal-draw Installs the hal-draw package.
ag list Lists all packages.
ag info hal-draw Shows information about hal-draw.
ag update hal-draw Updates the hal-draw package if it's not at the newest version.
ag update Updates all packages.
+8
View File
@@ -0,0 +1,8 @@
COMMAND beep
USAGE [FLAGS]
DESCRIPTION Make the computer beep.
ARG1 FLAGS
ARG1SUB1 -f, --frequency
ARG1SUB2 -t, --time
ARG1SUB1DESCRIPTION Specifies the frequency, in Hz. Defaults to 440Hz.
ARG1SUB2DESCRIPTION Specifies how long, in seconds, the computer should beep. Defaults to 0.1s.
-6
View File
@@ -1,6 +0,0 @@
Usage: beep [FLAGS]
Make the computer beep.
FLAGS
-f, --frequency Specifies the frequency, in Hz. Defaults to 440Hz.
-t, --time Specifies how long, in seconds, the computer should beep. Defaults to 0.1s.
+23
View File
@@ -0,0 +1,23 @@
COMMAND boot
USAGE [ADDRESS] [FLAGS]
DESCRIPTION Restarts and automatically boots into any storage medium. Meant to be used for systems using a Lua BIOS EEPROM.
ARG1 ADDRESS
ARG1SUB1 hdd1
ARG1SUB2 hdd2
ARG1SUB3 floppy
ARG1SUB4
ARG2 FLAGS
ARG2SUB1 -f, --force
ARG1DESCRIPTION The storage medium to boot to.
ARG1SUB1DESCRIPTION The first hard drive inserted in the computer.
ARG1SUB2DESCRIPTION The second hard drive inserted in the computer.
ARG1SUB3DESCRIPTION The floppy disk that is inserted in the computer.
ARG1SUB4DESCRIPTION The ID of the component, abbreviated. Must have three or more characters.
ARG2DESCRIPTION Specifies extra options when executing the command.
ARG2SUB1DESCRIPTION Forces booting into the storage medium.
EXAMPLE1 boot hdd1
EXAMPLE2 boot hdd2
EXAMPLE3 boot floppy
EXAMPLE1DESCRIPTION Boot into the first hard drive inserted in the computer.
EXAMPLE2DESCRIPTION Boot into the second hard drive inserted in the computer.
EXAMPLE3DESCRIPTION Boot into the floppy disk inserted in the comuter.
-15
View File
@@ -1,15 +0,0 @@
Usage: boot [ADDRESS] [FLAGS]
Restarts and automatically boots into any storage medium. Meant to be used for systems using a Lua BIOS EEPROM.
ADDRESS The storage medium to boot to.
hdd1 The first hard drive inserted in the computer.
hdd2 The second hard drive inserted in the computer.
floppy The floppy disk that is inserted in the computer.
The ID of the component, abbreviated. Must have three or more characters.
FLAGS Specifies extra options when executing the command.
-f, --force Forces booting into the storage medium.
Examples:
boot hdd1 Boot into the first hard drive inserted in the computer.
boot hdd2 Boot into the second hard drive inserted in the computer.
boot floppy Boot into the floppy disk inserted in the comuter.
+9
View File
@@ -0,0 +1,9 @@
COMMAND cat
USAGE [FILES]...
DESCRIPTION Concatenates and prints a file.
ARG1 FILES
ARG1DESCRIPTION Specifies the paths to the files to print.
EXAMPLE1 cat /init.lua
EXAMPLE2 cat help.lua cat.lua
EXAMPLE1DESCRIPTION Concatenates and prints init.lua in the root directory.
EXAMPLE2DESCRIPTION Concatenates and prints help.lua and cat.lua in the current working directory.
-8
View File
@@ -1,8 +0,0 @@
Usage: cat [FILES]...
Concatenates and prints a file.
FILES Specifies the paths to the files to print.
Examples:
cat /init.lua Concatenates and prints init.lua in the root directory.
cat help.lua cat.lua Concatenates and prints help.lua and cat.lua in the current working directory.
+13
View File
@@ -0,0 +1,13 @@
COMMAND cd
USAGE [PATH]
DESCRIPTION Sets the shell working directory.
ARG1 PATH
ARG1DESCRIPTION Specifies the path to set the shell working directory to.
EXAMPLE1 cd /home/
EXAMPLE2 cd halyde
EXAMPLE3 cd ..
EXAMPLE4 ..
EXAMPLE1DESCRIPTION Sets the shell working directory to /home/.
EXAMPLE2DESCRIPTION Sets the shell working directory to a directory named "halyde" in the current working directory.
EXAMPLE3DESCRIPTION Sets the shell working directory back one directory.
EXAMPLE4DESCRIPTION Equivalent of "cd ..".
-10
View File
@@ -1,10 +0,0 @@
Usage: cd [PATH]
Sets the shell working directory.
PATH Specifies the path to set the shell working directory to.
Examples:
cd /home/ Sets the shell working directory to /home/.
cd halyde Sets the shell working directory to a directory named "halyde" in the current working directory.
cd .. Sets the shell working directory back one directory.
.. Equivalent of "cd ..".
+4
View File
@@ -0,0 +1,4 @@
COMMAND clear
DESCRIPTION Clears the screen.
EXAMPLE1 clear
EXAMPLE1DESCRIPTION Clears the screen.
-5
View File
@@ -1,5 +0,0 @@
Usage: clear
Clears the screen.
Examples:
clear Clears the screen.
+11
View File
@@ -0,0 +1,11 @@
COMMAND cp
USAGE [SOURCES]... [DESTINATION]
DESCRIPTION Copy files and directories.
ARG1 SOURCES
ARG2 DESTINATION
ARG1DESCRIPTION Specifies the files and directories to be copied.
ARG2DESCRIPTION Specifies the path or a directory to copy to.
EXAMPLE1 cp /home/a.txt /b.txt
EXAMPLE2 cp c.lua /halyde/apps .
EXAMPLE1DESCRIPTION Copies the file at /home/a.txt to /b.txt.
EXAMPLE2DESCRIPTION Copies c.lua and /halyde/apps to the shell working directory.
-11
View File
@@ -1,11 +0,0 @@
Usage: cp [FLAGS] [SOURCE] [DESTINATION]
Copies a file.
FLAGS Specifies extra options when executing the command.
-o, --overwrite Allows any file that might be at the destination to be overwritten.
SOURCE Specifies the file to be copied.
DESTINATION Specifies the path to copy the file to.
Examples:
cp /home/a.txt /b.txt Copies the file at /home/a.txt to /b.txt.
cp -o c.lua d.txt Copies the file c.lua to another file called d.txt in the shell working directory, overwriting any file that might be there.
+7
View File
@@ -0,0 +1,7 @@
COMMAND download
USAGE [URL]
DESCRIPTION Downloads a file from the internet.
ARG1 URL
ARG1DESCRIPTION Specifies the URL from which to download the file from.
EXAMPLE1 download https://github.com/
EXAMPLE1DESCRIPTION Downloads github.com.
-7
View File
@@ -1,7 +0,0 @@
Usage: download [URL]
Downloads a file from the internet.
URL Specifies the URL from which to download the file from.
Examples:
download https://github.com/ Downloads github.com.
+9
View File
@@ -0,0 +1,9 @@
COMMAND echo
USAGE [TEXT]...
DESCRIPTION Concatenates and prints text to the terminal.
ARG1 TEXT
ARG1DESCRIPTION Text to print.
EXAMPLE1 echo test
EXAMPLE2 echo Hello World!
EXAMPLE1DESCRIPTION Prints "test" to the terminal.
EXAMPLE2DESCRIPTION Prints "Hello World!" to the terminal.
-8
View File
@@ -1,8 +0,0 @@
Usage: echo [TEXT]...
Concatenates and prints text to the terminal.
TEXT Text to print.
Examples:
echo test Prints "test" to the terminal.
echo Hello World! Prints "Hello World!" to the terminal.
+9
View File
@@ -0,0 +1,9 @@
COMMAND edit
USAGE [PATH]
DESCRIPTION Opens a file with the text editor, or a new blank file if not specified.
ARG1 PATH
ARG1DESCRIPTION Specifies the file to be opened.
EXAMPLE1 edit
EXAMPLE2 edit /LICENSE
EXAMPLE1DESCRIPTION Opens a new blank file in the text editor.
EXAMPLE2DESCRIPTION Opens /LICENSE in the text editor.
-8
View File
@@ -1,8 +0,0 @@
Usage: edit [PATH]
Opens a file with the text editor, or a new blank file if not specified.
PATH* Specifies the file to be opened.
Examples:
edit Opens a new blank file in the text editor.
edit /LICENSE Opens /LICENSE in the text editor.
+4
View File
@@ -0,0 +1,4 @@
COMMAND fetch
DESCRIPTION Displays system information including OS version, Lua version, memory, etc.
EXAMPLE1 fetch
EXAMPLE1DESCRIPTION Displays system information.
-5
View File
@@ -1,5 +0,0 @@
Usage: fetch
Displays system information including OS version, Lua version, memory, etc.
Examples:
fetch Displays system information.
+9
View File
@@ -0,0 +1,9 @@
COMMAND help
USAGE [COMMAND]
DESCRIPTION Displays info on the command specified, or a list of commands if one is not specified.
ARG1 COMMAND
ARG1DESCRIPTION Command to display information on.
EXAMPLE1 help
EXAMPLE2 help cp
EXAMPLE1DESCRIPTION Displays a list of all default commands available.
EXAMPLE2DESCRIPTION Displays information about the cp command.
-8
View File
@@ -1,8 +0,0 @@
Usage: help [COMMAND]
Displays info on the command specified, or a list of commands if one is not specified.
COMMAND* Command to display information on.
Examples:
help Displays a list of all default commands available.
help cp Displays information about the cp command.
+24
View File
@@ -0,0 +1,24 @@
COMMAND label
USAGE [ADDRESS] [LABEL]
DESCRIPTION Get or set a label of a component that supports labelling.
ARG1 ADDRESS
ARG1SUB1 eeprom
ARG1SUB2 halyde
ARG1SUB3 slotN
ARG1SUB4 #N
ARG2 LABEL
ARG1DESCRIPTION The component to use for getting or setting the label.
ARG1SUB1DESCRIPTION The computer's EEPROM.
ARG1SUB2DESCRIPTION The drive where the Halyde installation resides in.
ARG1SUB3DESCRIPTION The slot number of the drive, in top-to-bottom order (range 7-9)
ARG1SUB4DESCRIPTION The slot number of the drive, in drive space (range 1-3)
ARG1SUB5DESCRIPTION The ID of the component, abbreviated. Must have three or more characters.
ARG2DESCRIPTION The label to set the component to. If not found, the current label will be printed out.
EXAMPLE1 label #3
EXAMPLE2 label eeprom
EXAMPLE3 label slot8 Storage
EXAMPLE4 label halyde Halyde
EXAMPLE1DESCRIPTION Get the label of the third drive in the computer.
EXAMPLE2DESCRIPTION Get the label of the EEPROM inserted in the computer.
EXAMPLE3DESCRIPTION Set the drive at slot 8 to have the label "Storage"
EXAMPLE4DESCRIPTION Set the label of the Halyde installation to "Halyde"
-16
View File
@@ -1,16 +0,0 @@
Usage: label [ADDRESS] [LABEL]
Get or set a label of a component that supports labelling.
ADDRESS The component to use for getting or setting the label.
eeprom The computer's EEPROM.
halyde The drive where the Halyde installation resides in.
slotN The slot number of the drive, in top-to-bottom order (range 7-9)
#N The slot number of the drive, in drive space (range 1-3)
The ID of the component, abbreviated. Must have three or more characters.
LABEL* The label to set the component to. If not found, the current label will be printed out.
Examples:
label #3 Get the label of the third drive in the computer.
label eeprom Get the label of the EEPROM inserted in the computer.
label slot8 Storage Set the drive at slot 8 to have the label "Storage"
label halyde Halyde Set the label of the Halyde installation to "Halyde"
+19
View File
@@ -0,0 +1,19 @@
COMMAND log
USAGE [OPERATION] [ARGS]
DESCRIPTION Tool to manage system logs.
ARG1 OPERATION
ARG1SUB1 view [LOG]
ARG1SUB2 list
ARG1SUB3 clear [LOG]
ARG1SUB4 info/warn/error [LOG] [TEXT]
ARG2 ARGS
ARG1DESCRIPTION Operation to do with the system logs.
ARG1SUB1DESCRIPTION View a log file.
ARG1SUB2DESCRIPTION List all logs.
ARG1SUB3DESCRIPTION Clear a log file, or all if none specified.
ARG1SUB4DESCRIPTION Create a log entry for the specified log at the specified log level.
ARG2DESCRIPTION Arguments (specified under OPERATION)
EXAMPLE1 log view example
EXAMPLE2 log list
EXAMPLE3 log clear example
EXAMPLE4 log info example This is an example.
-15
View File
@@ -1,15 +0,0 @@
Usage: log [OPERATION] [ARGS]
Tool to manage system logs.
OPERATION Operation to do with the system logs.
view [LOG] View a log file.
list List all logs.
clear [LOG*] Clear a log file, or all if none specified.
info/warn/error [LOG] [TEXT] Create a log entry for the specified log at the specified log level.
ARGS Arguments (specified under OPERATION)
Examples:
log view example
log list
log clear example
log info example This is an example.
+11
View File
@@ -0,0 +1,11 @@
COMMAND ls
USAGE [PATH]...
DESCRIPTION Lists all files and directories in the specified path, or in the shell working directory if the path isn't specified. Directories are shown in yellow, executable files are shown in green, and other files are shown in white.
ARG1 PATH
ARG1DESCRIPTION Path to the directories to list files and subdirectories from.
EXAMPLE1 ls
EXAMPLE2 ls /halyde
EXAMPLE3 ls apps
EXAMPLE1DESCRIPTION Lists all files and directories from the current shell working directory.
EXAMPLE2DESCRIPTION Lists all files and directories from /halyde.
EXAMPLE3DESCRIPTION Lists all files and directories from the apps directory in the shell working directory.
-10
View File
@@ -1,10 +0,0 @@
Usage: ls [PATH]
Lists all files and directories in the specified path, or in the shell working directory if the path isn't specified.
Directories are shown in yellow, executable files are shown in green, and other files are shown in white.
PATH* Path to the folder to list files and directories from.
Examples:
ls Lists all files and directories from the current shell working directory.
ls /halyde Lists all files and directories from /halyde.
ls apps Lists all files and directories from the apps directory in the shell working directory.
+4
View File
@@ -0,0 +1,4 @@
COMMAND lscor
DESCRIPTION Lists every active coroutine by ID and name.
EXAMPLE1 lscor
EXAMPLE1DESCRIPTION Lists every active coroutine by ID and name.
-5
View File
@@ -1,5 +0,0 @@
Usage: lscor
Lists every active coroutine by ID and name.
Examples:
lscor Lists every active coroutine by ID and name.
+37
View File
@@ -0,0 +1,37 @@
COMMAND lsdrv
USAGE [FLAGS]
DESCRIPTION Shows all drives that are inserted into the computer.
ARG1 FLAGS
ARG1SUB1 -a, --all
ARG1SUB2 -o, --output [COLS]
ARG1SUB3 -s, --show [EXPR]
ARG1SUB4 -S, --sort [EXPR]
ARG1SUB5 EXPR
ARG2 PACKAGES
ARG1DESCRIPTION Specifies extra options when executing the command.
ARG1SUB1DESCRIPTION Shows every column and every component. Acts the same as '-o all -s all'. Possible columns are: "slot", "capacity", "managed", "readOnly", "id", "mount", "bootable", and "label". If the list of columns start with a "+", the default columns will appear first. Default columns are slots, capacity, the entire ID, the mount point, and the drive label.
ARG1SUB2DESCRIPTION Specifies the columns to output in the output table.
ARG1SUB3DESCRIPTION Only list drives when the expression returns 'true'.
ARG1SUB4DESCRIPTION Sort the output by an expression that returns a number. The higher the number, the lower the drive is displayed, and vice-versa.
ARG1SUB5DESCRIPTION An expression in Lua, for filtering or sorting output. If this expression contains spaces, make sure to put quotation marks on them!
ARG1SUB6DESCRIPTION Built-in variables are: "component", "computer", "type", "id", "readonly", "capacity", "managed", "eeprom", "halyde", "tmp", "proxy", "slot", and "all" (true).
EXAMPLE1 lsdrv
EXAMPLE2 lsdrv -a
EXAMPLE3 lsdrv -o +bootable
EXAMPLE4 lsdrv -o slot,label -s halyde
EXAMPLE5 lsdrv -o mount,capacity,label -s "not halyde"
EXAMPLE6 lsdrv -s type=='filesystem'
EXAMPLE7 lsdrv -s slot==1
EXAMPLE8 lsdrv -S capacity
EXAMPLE9 lsdrv -S -capacity
EXAMPLE10 lsdrv -o +managed -S managed
EXAMPLE1DESCRIPTION Show regular drives, with the default columns.
EXAMPLE2DESCRIPTION Show all storage components, with every column.
EXAMPLE3DESCRIPTION Show drives, with an added "bootable" category.
EXAMPLE4DESCRIPTION Show the slot and the label of the drive where Halyde is installed.
EXAMPLE5DESCRIPTION Show the mount points, capacities and labels of all drives other than Halyde.
EXAMPLE6DESCRIPTION Only show managed drives.
EXAMPLE7DESCRIPTION Show all drives that aren't physical (Virtual components, tmpfs)
EXAMPLE8DESCRIPTION Sort the drives by capacity, in ascending order.
EXAMPLE9DESCRIPTION Sort the drives by capacity, in descending order.
EXAMPLE10DESCRIPTION Show managed drives first, then unmanaged drives second, with an extra "managed" column.
-27
View File
@@ -1,27 +0,0 @@
Usage: lsdrv [FLAGS]
Shows all drives that are inserted into the computer.
FLAGS Specifies extra options when executing the command.
-a, --all Shows every column and every component. Acts the same as '-o all -s all'.
-o, --output [COLS] Specifies the columns to output in the output table.
Possible columns are: "slot", "capacity", "managed", "readOnly", "id", "mount", "bootable", and "label".
If the list of columns start with a "+", the default columns will appear first.
Default columns are slots, capacity, the entire ID, the mount point, and the drive label.
-s, --show [EXPR] Only list drives when the expression returns 'true'.
-S, --sort [EXPR] Sort the output by an expression that returns a number.
The higher the number, the lower the drive is displayed, and vice-versa.
EXPR An expression in Lua, for filtering or sorting output.
If this expression contains spaces, make sure to put quotation marks on them!
Built-in variables are: "component", "computer", "type", "id", "readonly", "capacity", "managed", "eeprom", "halyde", "tmp", "proxy", "slot", and "all" (true).
Examples:
lsblk Show regular drives, with the default columns.
lsblk -a Show all storage components, with every column.
lsblk -o +bootable Show drives, with an added "bootable" category.
lsblk -o slot,label -s halyde Show the slot and the label of the drive where Halyde is installed.
lsblk -o mount,capacity,label -s "not halyde" Show the mount points, capacities and labels of all drives other than Halyde.
lsblk -s type=='filesystem' Only show managed drives.
lsblk -s slot==1 Show all drives that aren't physical (Virtual components, tmpfs)
lsblk -S capacity Sort the drives by capacity, in ascending order.
lsblk -S -capacity Sort the drives by capacity, in descending order.
lsblk -o +managed -S managed Show managed drives first, then unmanaged drives second, with an extra "managed" column.
+4
View File
@@ -0,0 +1,4 @@
COMMAND lua
DESCRIPTION Starts the Lua shell, where you can type commands to interpret them in real time.
EXAMPLE1 lua
EXAMPLE1DESCRIPTION Starts the Lua shell.
-5
View File
@@ -1,5 +0,0 @@
Usage: lua
Starts the Lua shell, where you can type commands to interpret them in real time.
Examples:
lua Starts the Lua shell.
+2
View File
@@ -0,0 +1,2 @@
COMMAND maindrv
DESCRIPTION Shows the entire ID of the drive where Halyde is installed to.
-2
View File
@@ -1,2 +0,0 @@
Usage: maindrv
Shows the entire ID of the drive where Halyde is installed to.
+7
View File
@@ -0,0 +1,7 @@
COMMAND mkdir
USAGE [PATH]...
DESCRIPTION Makes a directory.
ARG1 PATH
ARG1DESCRIPTION Specifies the path to create the directory in.
EXAMPLE1 mkdir a
EXAMPLE1DESCRIPTION Creates a directory named a in the current shell working directory.
-7
View File
@@ -1,7 +0,0 @@
Usage: mkdir [PATH]
Makes a directory.
PATH Specifies the path to create the directory in.
Examples:
mkdir a Creates a directory named a in the current shell working directory.
+11
View File
@@ -0,0 +1,11 @@
COMMAND mv
USAGE [SOURCE].. [DESTINATION]
DESCRIPTION Moves/renames a file.
ARG1 SOURCE
ARG2 DESTINATION
ARG1DESCRIPTION Specifies the files and directories to be moved.
ARG2DESCRIPTION Specifies the path or a directory to copy to.
EXAMPLE1 mv /home/a.txt /b.txt
EXAMPLE2 mv ../c.lua /halyde/apps .
EXAMPLE1DESCRIPTION Moves the file at /home/a.txt to /b.txt.
EXAMPLE2DESCRIPTION Moves c.lua from a subdirectory and /halyde/apps to the shell working directory.
-11
View File
@@ -1,11 +0,0 @@
Usage: mv [FLAGS] [SOURCE] [DESTINATION]
Moves/renames a file.
FLAGS Specifies extra options when executing the command.
-o, --overwrite Allows any file that might be at the destination to be overwritten.
SOURCE Specifies the file to be moved/renamed.
DESTINATION Specifies the path/filename to move/rename the file to.
Examples:
mv /home/a.txt /b.txt Moves the file at /home/a.txt to /b.txt.
mv -o c.lua d.txt Renames the file c.lua to another file called d.txt in the shell working directory, overwriting any file that might be there.
+4
View File
@@ -0,0 +1,4 @@
COMMAND reboot
DESCRIPTION Reboots the computer.
EXAMPLE1 reboot
EXAMPLE1DESCRIPTION Reboots the computer.
-5
View File
@@ -1,5 +0,0 @@
Usage: reboot
Reboots the computer.
Examples:
reboot Reboots the computer.
+11
View File
@@ -0,0 +1,11 @@
COMMAND res
USAGE [FLAGS]
DESCRIPTION Gets or sets the current resolution.
ARG1 FLAGS
ARG1SUB1 [no flags]
ARG1SUB2 -x [number]
ARG1SUB3 -y [number]
ARG1DESCRIPTION Specifies extra options when executing the command.
ARG1SUB1DESCRIPTION Displays the current and maximum resolution.
ARG1SUB2DESCRIPTION Displays the current and maximum resolution on the x-axis. A new x-axis resolution can be specified as a number.
ARG1SUB3DESCRIPTION Displays the current and maximum resolution on the y-axis. A new y-axis resolution can be specified as a number.
-9
View File
@@ -1,9 +0,0 @@
Usage: res [FLAGS]
Gets or sets the current resolution.
FLAGS* Specifies extra options when executing the command.
[no flags] Displays the current and maximum resolution.
-x [number*] Displays the current and maximum resolution on the x-axis.
A new x-axis resolution can be specified as a number.
-y [number*] Displays the current and maximum resolution on the y-axis.
A new y-axis resolution can be specified as a number.
+7
View File
@@ -0,0 +1,7 @@
COMMAND rm
USAGE [PATH]...
DESCRIPTION Removes files and directories.
ARG1 PATH
ARG1DESCRIPTION Specifies the files and directories to be moved/renamed.
EXAMPLE1 rm a.txt
EXAMPLE1DESCRIPTION Removes a.txt in the current shell working directory.
-7
View File
@@ -1,7 +0,0 @@
Usage: rm [PATH]
Removes files and directories.
PATH Specifies the file to be moved/renamed.
Examples:
rm a.txt Removes a.txt in the current shell working directory.
+4
View File
@@ -0,0 +1,4 @@
COMMAND shutdown
DESCRIPTION Shuts down the computer.
EXAMPLE1 shutdown
EXAMPLE1DESCRIPTION Shuts down the computer.
-5
View File
@@ -1,5 +0,0 @@
Usage: shutdown
Shuts down the computer.
Examples:
shutdown Shuts down the computer.
+5
View File
@@ -0,0 +1,5 @@
COMMAND touch
USAGE [FILE]...
DESCRIPTION Create an empty file.
ARG1 FILE
ARG1DESCRIPTION The path of the files to create.
-6
View File
@@ -1,6 +0,0 @@
Usage: touch [FLAGS] [FILE]
Creates a file with empty content.
FLAGS Specifies extra options when executing the command.
-o, --overwrite Allows emptying out a file if it already exists.
FILE The path of the file to create.²
+9 -9
View File
@@ -1,7 +1,7 @@
local component = require("component")
local computer = require("computer")
local args = {...}
if not args then return print("\x1b[91mCannot get arguments.") end
if not args then return print("\x1b[91mCannot get arguments.\x1b[0m") end
if not args[1] then
return require("shell").run("help label")
end
@@ -29,27 +29,27 @@ elseif inputID:sub(1,1)=="#" and tonumber(inputID:sub(2)) then
componentFromSlot(slotNum)
elseif #inputID>=3 then
local fullID = component.get(inputID)
if not fullID then return print("\x1b[91mCould not find entire component ID from \""..inputID.."\".") end
if not fullID then return print("\x1b[91mCould not find entire component ID from \""..inputID.."\".\x1b[0m") end
comp = component.proxy(fullID)
else
print("\x1b[91mAddress must have atleast 3 characters")
print("\x1b[91mAddress must have atleast 3 characters\x1b[0m")
return require("shell").run("help label")
end
if not comp then
return print("\x1b[91mCould not find component from \""..inputID.."\".")
return print("\x1b[91mCould not find component from \""..inputID.."\".\x1b[0m")
end
local compID = comp.address
local function formatID(id)
return id:sub(1,8).."\x1b[37m"..id:sub(9).."\x1b[39m"
return id:sub(1,8).."\x1b[37m"..id:sub(9).."\x1b[0m"
end
local function unsupported(act)
print("This \x1b[92m"..(comp.type or "unknown").."\x1b[39m component doesn't support "..act.." labels.\nID: "..formatID(compID))
print("This \x1b[92m"..(comp.type or "unknown").."\x1b[0m component doesn't support "..act.." labels.\nID: "..formatID(compID).."\x1b[0m")
end
local function compError(act,reason)
print("\x1b[91mAn error occured while "..act.." the label of this component.\nComponent: "..(compID or "unknown id").." ("..((comp or {}).type or "unknown type")..")\n\n"..reason)
print("\x1b[91mAn error occured while "..act.." the label of this component.\nComponent: "..(compID or "unknown id").." ("..((comp or {}).type or "unknown type")..")\n\n"..reason.."\x1b[0m")
end
local function formatLabel(label)
@@ -67,7 +67,7 @@ if type(args[2])~="string" then
label = comp.getLabel()
end)
if success then
print("Label of "..formatID(compID)..((comp.type and comp.type~="filesystem") and " ("..comp.type..")" or "")..":\n \x1b[92m"..formatLabel(label).."\x1b[39m")
print("Label of "..formatID(compID)..((comp.type and comp.type~="filesystem") and " ("..comp.type..")" or "")..":\n \x1b[92m"..formatLabel(label).."\x1b[0m")
else
compError("getting",reason)
end
@@ -85,7 +85,7 @@ else
label = comp.setLabel(newLabel)
end)
if success then
print("Successfully set label of "..formatID(compID)..(comp.type and " ("..comp.type..")" or "").." to:\n \x1b[92m"..formatLabel(label).."\x1b[39m")
print("Successfully set label of "..formatID(compID)..(comp.type and " ("..comp.type..")" or "").." to:\n \x1b[92m"..formatLabel(label).."\x1b[0m")
else
compError("setting",reason)
end
+4 -4
View File
@@ -27,9 +27,9 @@ local function viewlog(logname)
entry = string.sub(entry, 1, -1)
end
if entry:sub(1, 4) == "WARN" then
print("\x1b[93m" .. entry)
print("\x1b[93m" .. entry .. "\x1b[0m")
elseif entry:sub(1, 5) == "ERROR" then
print("\x1b[91m" .. entry)
print("\x1b[91m" .. entry .. "\x1b[0m")
else
print(entry)
end
@@ -58,9 +58,9 @@ local function listlogs2()
print("Found \x1b[93m" .. #logs .. "\x1b[0m logs.")
for i in ipairs(logs) do
if i == #logs then
print("\x1b[93m└ \x1b[0m" .. logs[i] .. "\x1b[90m.log")
print("\x1b[93m└ \x1b[0m" .. logs[i] .. "\x1b[90m.log\x1b[0m")
else
print("\x1b[93m├ \x1b[0m" .. logs[i] .. "\x1b[90m.log")
print("\x1b[93m├ \x1b[0m" .. logs[i] .. "\x1b[90m.log\x1b[0m")
end
end
end
+48 -61
View File
@@ -1,71 +1,58 @@
local args = {...}
local target = args[1]
args = nil
local fs = require("filesystem")
local unicode = require("unicode")
local maxLength = 0
local margin = 2 -- minimum space between filename and size
local dirTable = {}
local fileTable = {}
local workingDirectory = require("shell").getWorkingDirectory()
local shell = require("shell")
if target then
if target:sub(1, 1) ~= "/" then
target = fs.concat(workingDirectory, target)
end
else
target = workingDirectory
local function formatSize(size, isDir)
if isDir then return "[DIR]" end
if size >= 1024^3 then return string.format("%.1fGiB", size / 1024^3) end
if size >= 1024^2 then return string.format("%.1fMiB", size / 1024^2) end
if size >= 1024 then return string.format("%.1fKiB", size / 1024) end
return size.."B"
end
local files = fs.list(target)
local function getFileColor(name, isDir)
if isDir then return "\27[93m" end
if name:match("%.lua$") then return "\27[92m" end
return "\27[0m"
end
if files then
local args = {...}
if not args[1] then
args = {require("shell").getWorkingDirectory()}
end
for _, path in pairs(args) do
path = shell.resolvePath(path)
local files = fs.list(path)
if not files then
terminal.write("\27[91mError: " .. path .. ": No such file or directory\27[0m\n")
goto continue
end
local fileList = {}
for _, file in pairs(files) do
if file:sub(-1, -1) == "/" then
table.insert(dirTable, file)
file = file:sub(1, -2)
else
table.insert(fileTable, file)
local isDir = file:sub(-1) == "/"
local name = isDir and file:sub(1, -2) or file
local size = isDir and 0 or fs.size(fs.concat(path, file))
table.insert(fileList, {name = name, isDir = isDir, size = size})
end
if unicode.wlen(file) > maxLength then
maxLength = unicode.wlen(file)
end
end
table.sort(dirTable)
table.sort(fileTable)
files = {}
for _, v in ipairs(dirTable) do
table.insert(files, v)
end
for _, v in ipairs(fileTable) do
table.insert(files, v)
end
dirTable, fileTable = nil, nil
for _, file in ipairs(files) do
local dir = false
local filetext
if file:sub(-1, -1) == "/" then
dir = true
filetext = "\27[93m"..file:sub(1, -2)
elseif file:find(".") and file:match("[^.]+$") == "lua" then
filetext = "\27[92m"..file
end
filetext = (filetext or file)..string.rep(" ", maxLength - unicode.wlen(file) + margin)
if dir then
print(filetext.." \27[0m[DIR]")
else
local size = fs.size(fs.concat(target, file))
local sizeString
if convert(size, "B", "GiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "GiB") * 100 + 0.5) / 100).." GiB"
elseif convert(size, "B", "MiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "MiB") * 100 + 0.5) / 100).." MiB"
elseif convert(size, "B", "KiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "KiB") * 100 + 0.5) / 100).." KiB"
else
sizeString = tostring(size).." B"
end
print(filetext.."\27[0m"..sizeString)
-- directories first
-- then files
table.sort(fileList, function(a, b)
if a.isDir ~= b.isDir then return a.isDir end
return a.name < b.name
end)
local maxSizeLen = 0
for _, item in ipairs(fileList) do
maxSizeLen = math.max(maxSizeLen, #formatSize(item.size, item.isDir))
end
terminal.write(path.."\n")
for _, item in ipairs(fileList) do
local sizeStr = formatSize(item.size, item.isDir)
sizeStr = string.rep(" ", maxSizeLen - #sizeStr) .. sizeStr
local color = getFileColor(item.name, item.isDir)
terminal.write(string.format("%s %s%s\27[0m\n", sizeStr, color, item.name))
end
::continue::
end
+4 -4
View File
@@ -77,7 +77,7 @@ elseif outArgIdx then
if headers[word] then
addHeader(word)
else
print("\x1b[93mCategory \""..word.."\" doesn't exist\x1b[39m")
print("\x1b[93mCategory \""..word.."\" doesn't exist\x1b[0m")
end
end
end
@@ -190,7 +190,7 @@ local function handleComponent(id,type)
if proxy.getLabel then
local clabel = proxy.getLabel()
label=clabel and serialize.string(clabel) or "None"
label=clabel and serialize(clabel) or "None"
else
label="Unsupported"
end
@@ -266,7 +266,7 @@ if not showAll then
if func then
filter(comps,func)
else
return print("\x1b[91mInvalid component filter:\n\n"..tostring(err).."\x1b[39m")
return print("\x1b[91mInvalid component filter:\n\n"..tostring(err).."\x1b[0m")
end
else
filter(comps,function(comp)
@@ -286,7 +286,7 @@ if sortArgIdx then
return (boolToNum(func(a)) or 0)<(boolToNum(func(b)) or 0)
end)
else
return print("\x1b[91mInvalid sort expression:\n\n"..tostring(err).."\x1b[39m")
return print("\x1b[91mInvalid sort expression:\n\n"..tostring(err).."\x1b[0m")
end
else
table.sort(comps,function(a,b)
+11 -8
View File
@@ -12,15 +12,18 @@ for _, lib in pairs(libList) do
local name = lib:match("(.+)%.lua")
_G[name] = require(name)
end
end, debug.traceback)
end, function(errMsg)
return errMsg .. "\n\n" .. debug.traceback()
end)
if not status then
local firstLine = tostring(err):match("^[^\n]*")
print(
string.format(
"\x1b[91mLibrary %s has failed loading:\n │ %s",
lib:match("(.+)%.lua"),
tostring(err or "unknown error"):match("^(.-)\n")
"\x1b[91mLibrary %s has failed loading:\n │ %s\x1b[0m",
lib:match("(.+)%.lua") or lib,
firstLine or "unknown error"
)
)
) -- TODO: only show first line of error
log.lua.error(
string.format(
'The library located at "%s" has failed loading:\n%s',
@@ -35,7 +38,7 @@ end
if failed then
print(
string.format(
'\x1b[93mOne or more libraries failed to load. For more information, check the log entries located at "%s".',
'\x1b[93mOne or more libraries failed to load. For more information, check the log entries located at "%s".\x1b[0m',
tostring(log.lua.logpath or "[unknown]")
)
)
@@ -59,7 +62,7 @@ while true do
returns = false
end
if not func then
return print("\x1b[91msyntax error: " .. (err or "unknown error"))
return print("\x1b[91msyntax error: " .. (err or "unknown error") .. "\x1b[0m")
end
local res = { func() }
if returns then
@@ -74,7 +77,7 @@ while true do
return errMsg .. "\n\n" .. debug.traceback()
end)
if not result then
print("\27[91m" .. reason)
print("\27[91m" .. reason .. "\27[0m")
end
end
end
+1 -1
View File
@@ -3,7 +3,7 @@
local computer = require("computer")
if type(computer)~="table" then
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m")
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[0m")
end
local address = computer.getBootAddress()
+18 -9
View File
@@ -1,14 +1,23 @@
local directory = ...
local fs = require("filesystem")
local shell = require("shell")
if not directory then
require("shell").run("help mkdir")
return
end
if directory:sub(1, 1) ~= "/" then
directory = fs.concat(require("shell").getWorkingDirectory(), directory)
local args = {...}
if not args[1] then
return shell.run("help mkdir")
end
for _, directory in pairs(args) do
directory = shell.resolvePath(directory)
if fs.exists(directory) then
print("\27[91mAn object already exists at the specified path.")
terminal.write("\27[91mError: " .. directory ..": An object already exists\27[0m\n")
goto continue
end
local what, err = fs.makeDirectory(directory)
if err ~= nil then
terminal.write("\27[91mError: " .. err .. "\27[0m\n")
goto continue
end
::continue::
end
fs.makeDirectory(directory)
+64 -19
View File
@@ -1,25 +1,70 @@
local fromFile, toFile = ...
local shell = require("shell")
local fs = require("filesystem")
local shell = require("shell")
if not fromFile or not toFile then
shell.run("help mv")
local args = {...}
if not args[1] then
return shell.run("help mv")
end
if not args[2] then
terminal.write("\27[91mError: No destination\27[0m\n")
return
end
if fromFile:sub(1, 1) ~= "/" then
fromFile = fs.concat(shell.getWorkingDirectory(), fromFile)
end
if toFile:sub(1, 1) ~= "/" then
toFile = fs.concat(shell.getWorkingDirectory(), toFile)
end
if fromFile == toFile then
print("\27[91mSource and destination are the same.")
end
if not fs.exists(fromFile) then
print("\27[91mSource file does not exist.")
end
if fs.exists(toFile) and not (table.find({...}, "-o") or table.find({...}, "--overwrite")) then
print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")
local dest = shell.resolvePath(args[#args])
if fs.isFile(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: Destination is not a directory\27[0m\n")
return
end
fs.rename(fromFile, toFile)
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
if fs.isDirectory(src) then
terminal.write("\27[91mError: Cannot write directory " .. src .. " to file " .. dest .. "\27[0m\n")
return
end
fs.rename(src, dest)
elseif fs.isDirectory(dest) then
for i = 1, #args - 1 do
local src = shell.resolvePath(args[i])
if src == dest then
terminal.write("\27[91mError: Source and destination are the same\27[0m\n")
goto continue
end
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
goto continue
end
fs.rename(src, fs.concat(dest, fs.basename(src)))
::continue::
end
elseif not fs.exists(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: " .. dest .. ": No such file or directory\27[0m\n")
return
end
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
local destp = fs.parent(dest)
if not fs.exists(destp) then
terminal.write("\27[91mError: " .. destp .. ": No such file or directory\27[0m\n")
return
end
if not fs.isDirectory(destp) then
terminal.write("\27[91mError: " .. destp .. ": Not a directory\27[0m\n")
return
end
fs.rename(src, dest)
else
terminal.write("\27[91mUnknown error\27[0m\n")
end
+15 -15
View File
@@ -9,7 +9,7 @@ local curX, curY = gpu.getResolution()
local function setRes()
if not(args[1] == "-x" or args[1] == "-y") then
print("\x1b[91mUnknown argument. \x1b[39mTry running \x1b[92m\"help res\"")
print("\x1b[91mUnknown argument. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
return
end
@@ -21,7 +21,7 @@ local function setRes()
x = tonumber(args[i + 1])
lastarg = "x"
else
print("\x1b[91mValue \"x\" was set more than once. \x1b[39mTry running \x1b[92m\"help res\"")
print("\x1b[91mValue \"x\" was set more than once. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
return
end
elseif args[i] == "-y" then
@@ -29,7 +29,7 @@ local function setRes()
y = tonumber(args[i + 1])
lastarg = "y"
else
print("\x1b[91mValue \"y\" was set more than once. \x1b[39mTry running \x1b[92m\"help res\"")
print("\x1b[91mValue \"y\" was set more than once. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
return
end
end
@@ -37,42 +37,42 @@ local function setRes()
if x then
if x > maxX then
print("\x1b[91mGPU does not support x higher than " .. maxX)
print("\x1b[91mGPU does not support x higher than " .. maxX .. "\x1b[0m.")
return
end
end
if y then
if y > maxY then
print("\x1b[91mGPU does not support y higher than " .. maxY)
print("\x1b[91mGPU does not support y higher than " .. maxY .. "\x1b[0m.")
return
end
end
if x and not(y) then
gpu.setResolution(x, curY)
print("Successfully set X resolution from \x1b[93m" .. curX .. "\x1b[39m to \x1b[92m" .. x .. "\x1b[39m.")
print("Successfully set X resolution from \x1b[93m" .. curX .. "\x1b[0m to \x1b[92m" .. x .. "\x1b[0m.")
return
elseif not(x) and y then
gpu.setResolution(curX, y)
print("Successfully set Y resolution from \x1b[93m" .. curY .. "\x1b[39m to \x1b[92m" .. y .. "\x1b[39m.")
print("Successfully set Y resolution from \x1b[93m" .. curY .. "\x1b[0m to \x1b[92m" .. y .. "\x1b[0m.")
return
else
gpu.setResolution(x, y)
print("Successfully set resolution from \x1b[93m" .. curX .. "x" .. curY .. "\x1b[39m to \x1b[92m" .. x .. "x" .. y .. "\x1b[39m.")
print("Successfully set resolution from \x1b[93m" .. curX .. "x" .. curY .. "\x1b[0m to \x1b[92m" .. x .. "x" .. y .. "\x1b[0m.")
return
end
end
local function getRes(val)
if val == "x" then
print("Current X resolution: \x1b[93m" .. curX)
print("Maximum supported X resolution: \x1b[92m" .. maxX)
print("Current X resolution: \x1b[93m" .. curX .. "\x1b[0m")
print("Maximum supported X resolution: \x1b[92m" .. maxX .. "\x1b[0m")
elseif val == "y" then
print("Current Y resolution: \x1b[93m" .. curY)
print("Maximum supported Y resolution: \x1b[92m" .. maxY)
print("Current Y resolution: \x1b[93m" .. curY .. "\x1b[0m")
print("Maximum supported Y resolution: \x1b[92m" .. maxY .. "\x1b[0m")
else
print("Current resolution: \x1b[93m" .. curX .. "x" .. curY)
print("Maximum supported resolution: \x1b[92m" .. maxX .. "x" .. maxY)
print("Current resolution: \x1b[93m" .. curX .. "x" .. curY .. "\x1b[0m")
print("Maximum supported resolution: \x1b[92m" .. maxX .. "x" .. maxY .. "\x1b[0m")
end
end
@@ -92,5 +92,5 @@ if axis == "-x" then
elseif axis == "-y" then
getRes("y")
else
print("\x1b[91mUnknown argument. \x1b[39mTry running \x1b[92m\"help res\"")
print("\x1b[91mUnknown argument. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
end
+12 -11
View File
@@ -1,16 +1,17 @@
local file = ...
local shell = require("shell")
local fs = require("filesystem")
local shell = require("shell")
if not file then
shell.run("help rm")
return
local args = {...}
if not args[1] then
return shell.run("help rm")
end
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.getWorkingDirectory(), file)
for _, file in pairs(args) do
file = shell.resolvePath(file)
local result = fs.remove(file)
if result == false then
terminal.write("\27[91mError: cannot delete " .. file .. "\27[0m\n")
end
if not fs.exists(file) then
print("\27[91mFile does not exist.")
return
end
fs.remove(file)
+1 -1
View File
@@ -88,4 +88,4 @@ end
end ]]
raster.free()
terminal.setCursorPos(1,1)
terminal.clear()
+11 -16
View File
@@ -1,28 +1,23 @@
-- TODO: Rename this to something else (while making an alias from the original command).
-- Touch seems kind of a silly name for a command to make a file.
-- Maybe something like mkfile would be better?
local cliparse = require("cliparse")
cliparse.config({
["o"] = 0,
["overwrite"] = 0,
})
local parsed = cliparse.parse(...)
local file = parsed.args[1]
local fs = require("filesystem")
local shell = require("shell")
if not file then
local args = {...}
if not args[1] then
return shell.run("help touch")
end
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.getWorkingDirectory(), file)
end
for _, file in pairs(args) do
file = shell.resolvePath(file)
if fs.exists(file) and not (parsed.flags.o or parsed.flags.overwrite) then
return print("\x1b[91mFile already exists.\n│ To empty file contents, use -o.")
local handle, err = fs.open(file, "a")
if err ~= nil then
terminal.write("\27[91mError: " .. err .. "\27[0m\n")
goto continue
end
local handle = fs.open(file, "w")
handle:write("") -- just in case
handle:close()
::continue::
end
+410 -167
View File
@@ -1,3 +1,10 @@
--[[
TODO:
```bash
echo -e "\033[?25l" # hide
echo -e "\033[?25h" # show
```
]]
local module = {}
function module.check()
@@ -9,23 +16,11 @@ function module.init()
local unicode = require("unicode")
local event = require("event")
--local ocelot = component.proxy(component.list("ocelot")())
local component = require("component")
local computer = require("computer")
local gpu = component.gpu
_G._PUBLIC.terminal = {}
local cursorPosX = 1
local cursorPosY = 1
local width, height = gpu.getResolution()
function _PUBLIC.terminal.getCursorPos()
return cursorPosX,cursorPosY
end
function _PUBLIC.terminal.setCursorPos(x,y)
checkArg(1,x,"number","nil")
checkArg(2,y,"number","nil")
if type(x)~=nil then cursorPosX=math.min(math.max(x,1),width) end
if type(y)~=nil then cursorPosY=math.min(math.max(y,1),height) end
end
local readHistory = {}
function _PUBLIC.terminal.getHistory(id)
checkArg(1,id,"string")
@@ -46,6 +41,28 @@ function module.init()
end
local ANSIColorPalette = {
["dark"] = {
[0] = 0x171421,
[1] = 0xc01c28,
[2] = 0x26a269,
[3] = 0xa2734c,
[4] = 0x12488b,
[5] = 0xa347ba,
[6] = 0x2aa1b3,
[7] = 0xd0cfcc
},
["bright"] = {
[0] = 0x5e5c64,
[1] = 0xf66151,
[2] = 0x33d17a,
[3] = 0xe9ad0c,
[4] = 0x2a7bde,
[5] = 0xc061cb,
[6] = 0x33c7de,
[7] = 0xffffff
}
}
--[[local ANSIColorPalette = {
["dark"] = {
[0] = 0x000000,
[1] = 0x800000,
@@ -66,172 +83,405 @@ function module.init()
[6] = 0x00FFFF,
[7] = 0xFFFFFF
}
}]]
local expecting_unicode_bytes = 0
local unicode_bytes_left = 0
local unicode_codepoint = 0
local cursor = { x = 1, y = 1, X = nil, Y = nil } -- X and Y are managed by ESC s and ESC u
local printState = 0 -- 0:none 1:in ESC 2:in CSI
local color = {
FG = ANSIColorPalette["bright"][7], BG = ANSIColorPalette["dark"][0],
fg = nil, bg = nil, reverse = false
}
color.fg = color.FG
color.bg = color.BG
local current_codepoint = 0
local bytes_remaining = 0
local seq = {}
defaultForegroundColor = ANSIColorPalette["bright"][7]
defaultBackgroundColor = ANSIColorPalette["dark"][0]
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
local function scrollDown()
if gpu.copy(1,1,width,height,0,-1) then
local prevForeground = gpu.getForeground()
local prevBackground = gpu.getBackground()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1, height, width, 1, " ")
gpu.setForeground(prevForeground)
gpu.setBackground(prevBackground)
cursorPosY=height
end
end
local function newLine()
cursorPosX=1
cursorPosY = cursorPosY + 1
if cursorPosY>height then
scrollDown()
end
end
local function parseCodeNumbers(code)
local o = {}
for num in code:sub(3,-2):gmatch("[^;]+") do
table.insert(o,tonumber(num))
end
return o
end
local function from8BitColor(num)
num=math.floor(num)&255
if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end
if num>=232 then return 0x10101*(8+(num-232)*10) end
num=num-16
local palette = {0,95,135,175,215,255}
return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1]
end
local function from24BitColor(r,g,b)
r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255
return (r<<16)|(g<<8)|b
end
local function findCodeEnd(text,i)
local function inRange(v,min,max)
return v>=min and v<=max
end
i=i+2
while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
return i
end
function _PUBLIC.terminal.write(text, textWrap)
-- you don't know how tiring this was just for ANSI escape code support
if textWrap == nil then
textWrap = true
end
if not text or not tostring(text) then
return
end
if text:find("\a") then
computer.beep()
end
text = tostring(text)
text = "\27[0m" .. text:gsub("\t", " ")
local readBreak = 0
-- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character.
-- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done.
local section = ""
local function printSection()
if #section==0 then
return
end
while true do
gpu.set(cursorPosX,cursorPosY,section)
if unicode.wlen(section) > width - cursorPosX + 1 and textWrap then
section = section:sub(width - cursorPosX + 2)
newLine()
local function update_gpu_colors()
if color.reverse then
gpu.setForeground(color.bg)
gpu.setBackground(color.fg)
else
cursorPosX = cursorPosX+unicode.wlen(section)
gpu.setForeground(color.fg)
gpu.setBackground(color.bg)
end
end
local width, height = gpu.getResolution()
function _G._PUBLIC.terminal.getResolution()
return width, height
end
gpu.setForeground(color.fg)
gpu.setBackground(color.bg)
local function scroll()
if gpu.copy(1, 2, width, height - 1, 0, -1) then
gpu.setForeground(color.FG)
gpu.setBackground(color.BG)
gpu.fill(1, height, width, 1, " ")
gpu.setForeground(color.fg)
gpu.setBackground(color.bg)
cursor.y = height
end
end
local function check_wrap_and_scroll()
if cursor.x > width then
cursor.x = 1
cursor.y = cursor.y + 1
end
while cursor.y > height do
scroll()
end
end
local function exec_csi()
local params = {}
local op = 0
local current_num = 0
local have_num = false
for i = 1, #seq do
local byte = seq[i]
if 0x30 <= byte and byte <= 0x39 then
current_num = current_num * 10 + (byte - 0x30)
have_num = true
elseif byte == 0x3b then
table.insert(params, have_num and current_num or 0)
current_num = 0
have_num = false
else
if have_num then
table.insert(params, current_num)
end
if 0x40 <= byte and byte <= 0x7e then
op = byte
end
break
end
end
section = ""
local function get_param(idx, default)
if idx <= #params and params[idx] ~= nil then
return params[idx]
end
return default
end
for i=1,#text do
if readBreak>0 then
readBreak = readBreak - 1
goto continue
if op == 0x48 or op == 0x66 then
local row = get_param(1, 1)
local col = get_param(2, 1)
cursor.y = row
cursor.x = col
if cursor.x < 1 then cursor.x = 1 end
if cursor.y < 1 then cursor.y = 1 end
if cursor.x > width then cursor.x = width end
if cursor.y > height then cursor.y = height end
return
end
if string.byte(text,i)==10 then
printSection()
newLine()
elseif string.byte(text,i)==13 then
printSection()
cursorPosX=1
elseif string.byte(text,i)==0x1b and i<=#text-2 then
printSection()
--ocelot.log("0x1b char detected")
local codeType = string.sub(text,i+1,i+1)
if codeType=="[" then
-- Control Sequence Introducer
--ocelot.log("Control Sequence Introducer")
local codeEndIdx = findCodeEnd(text,i)
-- codeEndIdx = string.find(text,"m",i)
local code = string.sub(text,i,codeEndIdx)
--ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")")
readBreak = readBreak + #code - 1
local nums = parseCodeNumbers(code)
local codeEnd = code:sub(-1)
--ocelot.log("Code end: "..codeEnd..", "..#codeEnd)
if codeEnd == "m" then
-- Select Graphic Rendition
--ocelot.log("Select Graphic Rendition, ID "..nums[1])
if nums[1]>=30 and nums[1]<=37 then
gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10])
if op == 0x41 then
local n = get_param(1, 1)
cursor.y = cursor.y - n
if cursor.y < 1 then cursor.y = 1 end
return
end
if nums[1]==38 and nums[2]==5 then
gpu.setForeground(from8BitColor(nums[3]))
if op == 0x42 then
local n = get_param(1, 1)
cursor.y = cursor.y + n
if cursor.y > height then cursor.y = height end
return
end
if nums[1]==38 and nums[2]==2 then
gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5]))
if op == 0x43 then
local n = get_param(1, 1)
cursor.x = cursor.x + n
if cursor.x > width then cursor.x = width end
return
end
if nums[1]==39 or nums[1]==0 then
gpu.setForeground(defaultForegroundColor)
if op == 0x44 then
local n = get_param(1, 1)
cursor.x = cursor.x - n
if cursor.x < 1 then cursor.x = 1 end
return
end
if nums[1]>=40 and nums[1]<=47 then
gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10])
if op == 0x47 then
local col = get_param(1, 1)
cursor.x = col
if cursor.x < 1 then cursor.x = 1 end
if cursor.x > width then cursor.x = width end
return
end
if nums[1]==48 and nums[2]==5 then
gpu.setBackground(from8BitColor(nums[3]))
if op == 0x4a then
local mode = get_param(1, 0)
if mode == 0 then
update_gpu_colors()
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, height - cursor.y + 1, " ")
elseif mode == 1 then
update_gpu_colors()
gpu.fill(1, 1, cursor.x, cursor.y, " ")
elseif mode == 2 then
update_gpu_colors()
gpu.fill(1, 1, width, height, " ")
cursor.x = 1
cursor.y = 1
end
if nums[1]==48 and nums[2]==2 then
gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5]))
return
end
if nums[1]==49 or nums[1]==0 then
gpu.setBackground(defaultBackgroundColor)
if op == 0x4b then
local mode = get_param(1, 0)
if mode == 0 then
update_gpu_colors()
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, 1, " ")
elseif mode == 1 then
update_gpu_colors()
gpu.fill(1, cursor.y, cursor.x, 1, " ")
elseif mode == 2 then
update_gpu_colors()
gpu.fill(1, cursor.y, width, 1, " ")
end
if nums[1]>=90 and nums[1]<=97 then
gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10])
return
end
if nums[1]>=100 and nums[1]<=107 then
gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10])
if op == 0x60 then
local col = get_param(1, 1)
cursor.x = col
if cursor.x < 1 then cursor.x = 1 end
if cursor.x > width then cursor.x = width end
return
end
if op == 0x64 then
local row = get_param(1, 1)
cursor.y = row
if cursor.y < 1 then cursor.y = 1 end
if cursor.y > height then cursor.y = height end
return
end
if op == 0x6d then
local j = 1
local function parse_extended_color()
local mode = get_param(j + 1, -1)
if mode == 5 then
local idx = get_param(j + 2, 0)
j = j + 2
if idx < 8 then
return ANSIColorPalette["dark"][idx]
elseif idx < 16 then
return ANSIColorPalette["bright"][idx - 8]
elseif idx < 232 then
local i = idx - 16
local b = (i % 6) * 51
local g = ((i // 6) % 6) * 51
local r = (i // 36) * 51
return (r << 16) | (g << 8) | b
else
local v = (idx - 232) * 10 + 8
return (v << 16) | (v << 8) | v
end
elseif mode == 2 then
local r = get_param(j + 2, 0)
local g = get_param(j + 3, 0)
local b = get_param(j + 4, 0)
j = j + 4
return (r << 16) | (g << 8) | b
end
return nil
end
if #params == 0 then
color.reverse = false
color.fg = color.FG
color.bg = color.BG
update_gpu_colors()
return
end
while j <= #params do
local p = params[j] or 0
if p == 0 then
color.reverse = false
color.fg = color.FG
color.bg = color.BG
elseif p == 1 then
elseif p == 2 then
elseif p == 3 then
elseif p == 4 then
elseif p == 5 or p == 6 then
elseif p == 7 then
color.reverse = true
elseif p == 8 then
color.fg = color.bg
elseif p == 9 then
elseif p == 21 then
elseif p == 22 then
elseif p == 23 then
elseif p == 24 then
elseif p == 25 then
elseif p == 27 then
color.reverse = false
elseif p == 28 then
color.fg = color.FG
elseif p == 29 then
elseif 30 <= p and p <= 37 then
color.fg = ANSIColorPalette["dark"][p - 30]
elseif p == 38 then
local c = parse_extended_color()
if c then color.fg = c end
elseif p == 39 then
color.fg = color.FG
elseif 40 <= p and p <= 47 then
color.bg = ANSIColorPalette["dark"][p - 40]
elseif p == 48 then
local c = parse_extended_color()
if c then color.bg = c end
elseif p == 49 then
color.bg = color.BG
elseif p == 58 then
parse_extended_color()
elseif p == 59 then
elseif 90 <= p and p <= 97 then
color.fg = ANSIColorPalette["bright"][p - 90]
elseif 100 <= p and p <= 107 then
color.bg = ANSIColorPalette["bright"][p - 100]
end
j = j + 1
end
update_gpu_colors()
return
end
if op == 0x73 then
cursor.X = cursor.x
cursor.Y = cursor.y
return
end
if op == 0x75 then
if cursor.X and cursor.Y then
cursor.x = cursor.X
cursor.y = cursor.Y
if cursor.x < 1 then cursor.x = 1 end
if cursor.y < 1 then cursor.y = 1 end
if cursor.x > width then cursor.x = width end
if cursor.y > height then cursor.y = height end
end
return
end
end
function _G._PUBLIC.terminal.writec(byte)
if byte == 0x1b then
printState = 1
seq = {}
return
end
if printState == 1 then
if byte == 0x5b then
printState = 2
else
printState = 0
end
return
end
if printState == 2 then
table.insert(seq, byte)
if 0x40 <= byte and byte <= 0x7e then
exec_csi()
printState = 0
seq = {}
end
return
end
if byte == 0xa then
cursor.y = cursor.y + 1
cursor.x = 1
check_wrap_and_scroll()
return
end
if byte == 0xd then
cursor.x = 1
return
end
if byte == 0x8 then
if cursor.x > 1 then
cursor.x = cursor.x - 1
end
return
end
if byte == 0x9 then
cursor.x = ((cursor.x - 1) // 8) * 8 + 9
if cursor.x < 1 then cursor.x = 1 end
if cursor.x > width then cursor.x = width end
return
end
if byte >= 0x00 and byte <= 0x7F then
update_gpu_colors()
gpu.set(cursor.x, cursor.y, string.char(byte))
cursor.x = cursor.x + 1
check_wrap_and_scroll()
elseif byte >= 0xC2 and byte <= 0xDF then
current_codepoint = (byte & 0x1F)
bytes_remaining = 1
elseif byte >= 0xE0 and byte <= 0xEF then
current_codepoint = (byte & 0x0F)
bytes_remaining = 2
elseif byte >= 0xF0 and byte <= 0xF7 then
current_codepoint = (byte & 0x07)
bytes_remaining = 3
elseif byte >= 0x80 and byte <= 0xBF and bytes_remaining > 0 then
current_codepoint = (current_codepoint << 6) | (byte & 0x3F)
bytes_remaining = bytes_remaining - 1
if bytes_remaining == 0 then
local char = utf8.char(current_codepoint)
update_gpu_colors()
gpu.set(cursor.x, cursor.y, char)
cursor.x = cursor.x + 1
check_wrap_and_scroll()
current_codepoint = 0
end
else
--gpu.set(cursorPosX,cursorPosY,string.sub(text,i,i))
section = section..string.sub(text,i,i)
current_codepoint = 0
bytes_remaining = 0
end
::continue::
end
printSection()
function _G._PUBLIC.terminal.write(text)
text = tostring(text)
for i = 1, #text do
_PUBLIC.terminal.writec(string.byte(text, i))
end
end
function _G._PUBLIC.terminal.clear()
update_gpu_colors()
gpu.fill(1, 1, width, height, " ")
cursor.x = 1
cursor.y = 1
end
function _G.print(...)
@@ -239,19 +489,12 @@ function module.init()
local stringArgs = {}
for _, arg in pairs(args) do
if type(arg)=="table" then
table.insert(stringArgs, serialize.table(arg,true))
table.insert(stringArgs, serialize(arg))
elseif tostring(arg) then
table.insert(stringArgs, tostring(arg))
end
end
_PUBLIC.terminal.write(table.concat(stringArgs, " ") .. "\n")
end
function _G._PUBLIC.terminal.clear()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1,1,width,height," ")
cursorPosX, cursorPosY = 1, 1
_PUBLIC.terminal.write(table.concat(stringArgs, "\t") .. "\n")
end
function _G._PUBLIC.terminal.read(options)
@@ -289,7 +532,7 @@ function module.init()
local cur = unicode.len(text)+1
if options.prefix then _PUBLIC.terminal.write(options.prefix) end
local startX, startY = cursorPosX, cursorPosY
local startX, startY = cursor.x, cursor.y
local fg, bg = gpu.getForeground(), gpu.getBackground()
local cursorBlink = true
local function checkScroll(y)
@@ -482,9 +725,9 @@ function module.init()
end
end
cursorPosX=1
cursorPosY=cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width)
if cursorPosY>height then scrollDown() end
cursor.x=1
cursor.y=cursor.y+math.ceil((unicode.wlen(text)+startX-1)/width)
if cursor.y>height then scroll() end
return text
end
+1 -1
View File
@@ -42,7 +42,7 @@ function module.init()
if type(tsched.currentTask) == "table" and type(tsched.currentTask.id) == "number" then
taskInfo.parent = tsched.currentTask.id
else
log.kernel.info("debug: tsched.currentTask is " .. require("serialize").table(tsched.currentTask))
log.kernel.info("debug: tsched.currentTask is " .. require("serialize")(tsched.currentTask))
end
table.insert(tsched.tasks, taskInfo)
if taskInfo.parent then
+5
View File
@@ -22,6 +22,11 @@ function _G.shell.getWorkingDirectory()
return workingDirectory
end
function _G.shell.resolvePath(path)
if path:sub(1, 1) == "/" then return path end
return fs.concat(workingDirectory, path)
end
function _G.shell.setWorkingDirectory(dir)
checkArg(1, dir, "string")
workingDirectory = dir
+22 -19
View File
@@ -32,6 +32,11 @@ function filesystem.canonical(path)
return "/" .. table.concat(segList, "/")
end
function filesystem.basename(path)
checkArg(1, path, "string")
return path:match("/([^/]+)/?$") or ""
end
function filesystem.concat(path1, path2)
checkArg(1, path1, "string")
checkArg(2, path2, "string")
@@ -67,6 +72,13 @@ function filesystem.absolutePath(path) -- returns the address and absolute path
return address, path
end
function filesystem.parent(path)
checkArg(1, path, "string")
local p = filesystem.canonical(path)
-- return "/" on "/"
return p == "/" and "/" or (p:match("^(.*)/[^/]+/?$") or "/")
end
function filesystem.exists(path) -- check if path exists
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
@@ -475,14 +487,12 @@ local function copyContent(fromHandle, toHandle)
if not (fromHandle and toHandle) then
return
end
local memory = math.floor(computer.freeMemory() * 0.8)
local tmpdata
while true do
tmpdata = fromHandle:read(memory)
local tmpdata = fromHandle.read(2048)
if not tmpdata then
break
end
local status, reason = toHandle:write(tmpdata)
local status, reason = toHandle.write(tmpdata)
if status ~= true then
break
end
@@ -492,7 +502,6 @@ local function copyContent(fromHandle, toHandle)
end
local function copyRecursive(fromAddress, fromAbsPath, toAddress, toAbsPath)
-- TODO: make this use copyContent
if fromAbsPath:sub(-1) == "/" then
fromAbsPath = fromAbsPath:sub(1, -2)
end
@@ -506,31 +515,21 @@ local function copyRecursive(fromAddress, fromAbsPath, toAddress, toAbsPath)
end
for i = 1, #fileList do
local fromFile, toFile = fromAbsPath .. "/" .. fileList[i], toAbsPath .. "/" .. fileList[i]
--[[ local handle = component.invoke(fromAddress, "open", fromFile, "r")
local data, tmpdata = "", nil
repeat
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = component.invoke(fromAddress, "close", handle)
local handle = component.invoke(toAddress, "open", toFile, "w")
component.invoke(toAddress, "write", handle, data)
component.invoke(toAddress, "close", handle) ]]
local fromHandle = component.invoke(fromAddress, "open", fromFile, "r")
local toHandle = component.invoke(toAddress, "open", toFile, "w")
copyContent({
["read"] = function(...)
return component.invoke(fromAddress, "read", handle, ...)
return component.invoke(fromAddress, "read", fromHandle, ...)
end,
["close"] = function(...)
return component.invoke(fromAddress, "close", handle, ...)
return component.invoke(fromAddress, "close", fromHandle, ...)
end,
}, {
["write"] = function(...)
return component.invoke(fromAddress, "write", handle, ...)
return component.invoke(toAddress, "write", toHandle, ...)
end,
["close"] = function(...)
return component.invoke(fromAddress, "close", handle, ...)
return component.invoke(toAddress, "close", toHandle, ...)
end,
})
end
@@ -545,6 +544,10 @@ function filesystem.isDirectory(path)
return component.invoke(address, "isDirectory", absPath)
end
function filesystem.isFile(path)
return not filesystem.isDirectory(path) and filesystem.exists(path)
end
function filesystem.rename(fromPath, toPath)
checkArg(1, fromPath, "string")
checkArg(2, toPath, "string")
+43 -122
View File
@@ -1,127 +1,48 @@
local serialize = {}
function serialize.string(str)
return '"'..str:gsub("[%z\1-\31\34\92\127-\159]",function(c)
local byte = c:byte()
if byte== 7 then return "\\a" end
if byte== 8 then return "\\b" end
if byte== 9 then return "\\t" end
if byte==10 then return "\\n" end
if byte==11 then return "\\v" end
if byte==12 then return "\\f" end
if byte==13 then return "\\r" end
if byte==34 then return "\\\"" end
if byte==92 then return "\\\\" end
return string.format("\\x%02x",byte)
end)..'"'
local function _serialize(value, indent, level, visited)
local currentIndent = indent and string.rep(indent, level) or ""
local nextIndent = indent and string.rep(indent, level + 1) or ""
local sep = indent and "\n" or " "
local t = type(value)
if t == "nil" then return "nil" end
if t == "string" then return string.format("%q", value) end
if t == "number" then
if value ~= value then return "0/0" end
if value == math.huge then return "math.huge" end
if value == -math.huge then return "-math.huge" end
return tostring(value)
end
if t == "boolean" then return tostring(value) end
if t == "table" then
if visited[value] then return "..." end
visited[value] = true
local items = {}
local arrayCount = 0
for i = 1, #value do
if value[i] ~= nil then arrayCount = i else break end
end
for i = 1, arrayCount do
table.insert(items, nextIndent .. _serialize(value[i], indent, level + 1, visited))
end
for k, v in pairs(value) do
if type(k) ~= "number" or k < 1 or k > arrayCount then
local keyStr
if type(k) == "string" and k:match("^[%a_][%w_]*$") then
keyStr = k
else
keyStr = "[" .. _serialize(k, indent, level + 1, visited) .. "]"
end
table.insert(items, nextIndent .. keyStr .. " = " .. _serialize(v, indent, level + 1, visited))
end
end
visited[value] = nil
if #items == 0 then return "{}" end
return "{" .. sep .. table.concat(items, "," .. sep) .. sep .. currentIndent .. "}"
end
return tostring(value)
end
function serialize.table(tbl,colors,stack)
stack = table.copy(stack or {})
table.insert(stack,tbl)
local keyAmount = 0
local keyNumber = true
local out = ""
local first = true
for key,val in pairs(tbl) do
if not first then out=out..",\n" end
first=false
out=out.." "
if type(key)=="string" then
if key:match("^[%a_][%w_]*$") then
out=out..key.."="
else
out=out..'['..serialize.string(key)..']='
end
else
out=out.."["..tostring(key).."]="
end
if type(key)~="number" then
keyNumber=false
end
local success,reason = pcall(function()
local valStr = ""
if type(val)=="table" then
if #stack>4 or table.find(stack,val) then
valStr="..."
else
valStr=serialize.table(val,colors,stack)
end
elseif type(val)=="string" then
local lines = {}
for line in (val.."\n"):gmatch("([^\n]*)\n") do table.insert(lines,line) end
if #lines[#lines]==0 then
lines[#lines]=nil
lines[#lines]=lines[#lines].."\n"
end
for i=1,#lines do
if i<#lines then
lines[i]=serialize.string(lines[i].."\n")
else
lines[i]=serialize.string(lines[i])
end
end
valStr=table.concat(lines," ..\n ")
else
valStr=tostring(val)
end
local lines = {}
for line in (valStr.."\n"):gmatch("([^\n]*)\n") do table.insert(lines,line) end
out=out..table.concat(lines,"\n ")
lines = nil
keyAmount=keyAmount+1
end)
if not success then
if colors then out=out.."\x1b[91m" end
out=out.."["..tostring(reason).."]"
if colors then out=out.."\x1b[39m" end
end
coroutine.yield()
end
local metatbl = getmetatable(tbl)
local metakeys = {}
local metastring = ""
if type(metatbl)=="table" then
for i,v in pairs(metatbl) do
keyNumber=false
table.insert(metakeys,i)
end
end
if #metakeys>0 then
out=out.."\n "
if colors then metastring=metastring.."\x1b[92m" end
if table.find(metakeys,"__tostring") then
metastring=metastring.."tostring: "..serialize.string(tostring(tbl)).."\n "
table.remove(metakeys,table.find(metakeys,"__tostring"))
end
metastring=metastring..table.concat(metakeys,", ")
if colors then metastring=metastring.."\x1b[39m" end
out=out..metastring
end
if keyAmount==0 then return "{"..metastring.."}" end
if keyNumber then
-- fix strings not being serialised
local vals = {}
for _,v in pairs(tbl) do
if #vals>=5 and #stack>1 then
table.insert(vals,"...")
break
end
if type(v)=="table" then
table.insert(vals,serialize.table(v,colors,stack))
elseif type(v)=="string" then
table.insert(vals,serialize.string(v))
else
table.insert(vals,tostring(v))
end
end
return "{"..table.concat(vals,", ")..(#metakeys>0 and "\n "..metastring or "").."}"
end
return "{\n"..out.."\n}"
function serialize(value, indent)
return _serialize(value, indent, 0, {})
end
return serialize
+1 -1
View File
@@ -236,7 +236,7 @@ local function startTransaction(dbpath)
function transaction.addInfo(name,info)
if not info.type then info.type="package" end
packInfo[name]=info
-- print(require("serialize").table(packInfo))
-- print(require("serialize")(packInfo))
end
local function getPackInfo(pack)