14 Commits

Author SHA1 Message Date
WahPlus 3d91323ea7 Added Gitea migration warning 2026-06-20 10:12:33 +03:00
WahPlus 6c7e9ccc5e Changed README shield to say DokuWiki 2026-06-20 10:12:24 +03:00
WahPlus da63451e0b Added DokuWiki docs to README 2026-06-20 10:12:16 +03:00
github-actions[bot] 53710672c7 But did YOU know (minified) 2026-04-30 15:09:56 +00:00
github-actions[bot] 663354f781 AFSDHJFJKHDSAFHJKSHJKFJHDFJSKOAPOPJIUFSJIFOPSA (minified) 2026-04-30 15:07:25 +00:00
github-actions[bot] 32ff91d1d0 Ponali the legend comes in clutch once again (minified) 2026-04-30 13:13:20 +00:00
github-actions[bot] 8535cb9380 DO YOU WANT A BANANA (minified) 2026-04-30 13:01:41 +00:00
github-actions[bot] b7b7b3e569 kukgug (minified) 2026-04-30 12:55:30 +00:00
github-actions[bot] a5cd53656a Bwomp (minified) 2026-04-30 12:50:37 +00:00
github-actions[bot] 6f2a561e3d I'm gonna go instane (minified) 2026-04-30 12:45:25 +00:00
github-actions[bot] b08d7b3f98 I forgot you have to give it write permissions (minified) 2026-04-30 12:32:52 +00:00
WahPlus 2a2b27a827 Made filesystem.concat() work with more than 2 paths
Also made the code a bit cleaner.
2026-03-04 17:42:06 +02:00
WahPlus 9581d5ce52 Added MD5 library 2025-10-27 20:08:04 +02:00
WahPlus 2dee5eaba7 Revert pre-alpha 3.0.0 because I was supposed to push it to a branch.
This reverts commit cbf25999f0.
2025-08-17 16:44:40 +03:00
141 changed files with 400 additions and 9374 deletions
-3
View File
@@ -1,3 +0,0 @@
[*.lua]
indent_style = space
indent_size = 2
+14
View File
@@ -0,0 +1,14 @@
const fs = require("fs")
const luamin = require('lua-format')
const Code = fs.readFileSync(process.argv[2],"utf-8")
const Settings = {
RenameVariables: true,
RenameGlobals: false,
SolveMath: true,
Indentation: '\t'
}
const Beautified = luamin.Beautify(Code, Settings)
const Minified = luamin.Minify(Code, Settings)
fs.writeFileSync(process.argv[2],"utf-8")
+55
View File
@@ -0,0 +1,55 @@
name: Minify all Lua files to minified branch
on:
push:
branches:
- main
jobs:
minify:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout main branch
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Get latest commit info
id: commit
run: |
COMMIT_MSG=$(git log -1 --pretty=%s)
echo "message=${COMMIT_MSG}" >> $GITHUB_OUTPUT
- name: Set up Node.js
uses: actions/setup-node@v4
- name: Install luamin
run: npm install -g luamin
- name: Switch to minified branch
run: git checkout minified
- name: Copy files from main
run: |
git checkout main -- .
git reset HEAD
- name: Minify all Lua files
run: |
for file in $(find . -name "*.lua" -not -path "./.git/*"); do
echo $file
cat "$file" | luamin -c > "$file"
done
- name: Commit and push to minified branch
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "${{ steps.commit.outputs.message }} (minified)"
git push origin minified
-5
View File
@@ -1,5 +0,0 @@
.stfolder
.idea
home/*
halyde/logs/*
*.kate-swp
+7 -98
View File
@@ -1,101 +1,10 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/lua-language-server/master/locale/en-us/setting.lua",
"runtime": {
"version": "Lua 5.3",
"special": {},
"unicodeName": false,
"nonstandardSymbol": []
},
"workspace": {
"checkThirdParty": false,
"maxPreload": 5000,
"preloadFileSize": 500
},
"diagnostics": {
"disable": [
"undefined-global",
"lowercase-global",
"missing-fields"
"diagnostics.globals": [
"checkArg",
"computer",
"component"
],
"globals": [
"_G",
"_VERSION",
"assert",
"error",
"getmetatable",
"ipairs",
"load",
"next",
"pairs",
"pcall",
"rawequal",
"rawget",
"rawlen",
"rawset",
"select",
"setmetatable",
"tonumber",
"tostring",
"type",
"xpcall",
"checkArg",
"bit32",
"coroutine",
"debug",
"math",
"os",
"string",
"table",
"component",
"computer",
"unicode",
"utf8"
"diagnostics.disable": [
"lowercase-global"
]
},
"completion": {
"enable": true,
"callSnippet": "Both",
"keywordSnippet": "Both",
"displayContext": 6
},
"hover": {
"enable": true,
"viewString": true,
"viewStringMax": 1000,
"viewNumber": true,
"fieldInfer": 3000,
"previewFields": 50,
"enumsLimit": 5
},
"semantic": {
"enable": true,
"variable": true,
"annotation": true,
"keyword": false
},
"format": {
"enable": true,
"defaultConfig": {
"indent_style": "space",
"indent_size": "2",
"tab_width": "2"
}
},
"spell": {
"dict": []
},
"telemetry": {
"enable": false
},
"IntelliSense": {
"traceLocalSet": false,
"traceReturn": false,
"traceBeSetted": false,
"traceFieldInject": false
},
"type": {
"castNumberToInteger": false,
"weakUnionCheck": false,
"weakNilCheck": false
}
}
}
+25 -23
View File
@@ -1,23 +1,25 @@
# Halyde
A universal, customizable and feature-packed operating system for OpenComputers.
<p align="center">
<a href="https://lua.org/">
<img src="https://img.shields.io/badge/Written_in-Lua-blue?style=plastic&logo=lua" /></a>
<a href="https://ocdoc.cil.li/">
<img src="https://img.shields.io/badge/Made_for-OpenComputers-yellow?style=plastic" /></a>
<a href="https://cerulean-blue.gitbook.io/halyde-docs">
<img src="https://img.shields.io/badge/Documented_on-GitBook-green?style=plastic&logo=gitbook" /></a>
</p>
## Installation
To install Halyde from OpenOS, simply run:
`pastebin run MB21BTMv`
If for some reason that doesn't work, try:
`wget -f https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/webinstall.lua /tmp/webinstall.lua && /tmp/webinstall.lua`
## Docs
Halyde is [documented on GitBook](https://cerulean-blue.gitbook.io/halyde-docs).
# Halyde
### If you are viewing on GitHub: Halyde has moved to [Gitea](https://git.sting.lt/Cerulean-Blue/Halyde). This repository is now a read-only mirror. Contributions, issues and pull requests will not be processed here. Please go to [the Gitea instance](https://git.sting.lt/Cerulean-Blue/Halyde) for that.
A universal, customizable and feature-packed operating system for OpenComputers.
<p align="center">
<a href="https://lua.org/">
<img src="https://img.shields.io/badge/Written_in-Lua-blue?style=plastic&logo=lua" /></a>
<a href="https://ocdoc.cil.li/">
<img src="https://img.shields.io/badge/Made_for-OpenComputers-yellow?style=plastic" /></a>
<a href="https://wiki.sting.lt/">
<img src="https://img.shields.io/badge/Documented_on-DokuWiki-green?style=plastic" /></a>
</p>
## Installation
To install Halyde from OpenOS, simply run:
`pastebin run MB21BTMv`
If for some reason that doesn't work, try:
`wget -f https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/webinstall.lua /tmp/webinstall.lua && /tmp/webinstall.lua`
## Docs
Halyde is [documented on DokuWiki](https://wiki.sting.lt/), however there is an alternative documentation on [GitBook](https://cerulean-blue.gitbook.io/halyde-docs/).
-9
View File
@@ -1,9 +0,0 @@
{
"halyde": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"argentum": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"edit": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"package1": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"package2": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"vpkg": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"grouper": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/"
}
+1 -5
View File
@@ -1,4 +1,3 @@
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/",
@@ -9,10 +8,7 @@ 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/",
["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/"
["ctif-viewer"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/"
}
return agregistry
-520
View File
@@ -1,520 +0,0 @@
local cliparse = require("cliparse")
local fs = require("filesystem")
local component = require("component")
local json = require("json")
local function getFile(path)
checkArg(1, path, "string")
if path:sub(1, 7) == "http://" or path:sub(1, 8) == "https://" then
if not component.list("internet")() then
return false, "Internet card required but not found."
end
local handle, data, tmpdata = component.internet.request(path), "", nil
local success, errorMessage = pcall(function()
handle:finishConnect()
end)
if not success then
return false, errorMessage
end
local code, message = handle:response()
if code and code ~= 200 then
return false, ("%d %s"):format(code, message)
end
repeat
tmpdata = handle.read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
return true, data
elseif path:sub(1, 1) == "/" then
if not fs.exists(path) then
return false, "No such file or directory: " .. path
end
if fs.isDirectory(path) then
return false, "Expected file, found directory: " .. path
end
local handle, data, tmpdata = fs.open(path, "r", false), "", nil
if not handle then
return false, data
end
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
return true, data
else
return false, "Unsupported path: " .. path
end
end
cliparse.config({
["x"] = 0,
["exclude-deps"] = 0,
["u"] = 0,
["update-registry"] = 0,
["f"] = 0,
["force"] = 0,
["c"] = 0,
["clean"] = 0,
["s"] = 1,
["source"] = 1,
["C"] = 0,
["cascade"] = 0,
})
local parsed, errorMessage = cliparse.parse(...)
if not parsed then
print(("\27[91m%s\n\27[0mExiting."):format(errorMessage))
return
end
local command = parsed.args[1]
if not command then
print("\27[91mNo command specified.\n\27[0mExiting.")
return
end
if
not (
command == "install"
or command == "remove"
or command == "update"
or command == "list"
or command == "repo-list"
or command == "repo-add"
or command == "repo-remove"
or command == "info"
)
then
print(("\27[91mInvalid command: %s\n\27[0mExiting."):format(command))
return
end
local packages = parsed.args
table.remove(packages, 1)
-- Remove the command from the actual package list
-- local result, data, failure
do
local function check(condition, message)
if not condition then
print(message)
failure = true
end
end
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 .. "\27[0m")
local handle, errorMessage = fs.open("/ag2/registry.json", "w")
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 .. "\27[0m")
handle:close()
else
result, data = getFile("/ag2/registry.json")
check(result, "\27[91mFailed to get registry: " .. data .. "\27[0m")
end
end
local success, registry = pcall(function()
return json.decode(data)
end)
if not success then
print(("\27[91mFailed to parse registry: %s\n\27[0mExiting."):format(registry))
return
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 .. "\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 .. "\27[0m"):format(package)
end
if not packageConfig[package] then
return false, ("\27[91mRepository package config (ag2.json) does not contain package '%s'.\27[0m"):format(package)
end
return packageConfig[package]
end
-- Check if everything is valid
failure = false
local dependencyCounter = 0
local previousI = 1 -- See 190
::RESETLOOP::
if command == "install" then
for i = previousI, #packages do
if not packages[i] then
-- When packages are removed, the last packages can end up reading as nil
goto SKIP
end
local otherPackages = table.copy(packages)
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\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
end
local source
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[packages[i]]
end
if not source then
print("\27[91mCould not find package in registry and no source provided: " .. packages[i] .. "\27[0m")
failure = true
goto SKIP
end
local packageConfig, errorMessage = getServersidePackageConfig(source, packages[i])
if not packageConfig then
failure = true
print(errorMessage)
goto SKIP
end
if packageConfig.type == "group" then
table.remove(packages, i)
for _, package in ipairs(packageConfig.packages) do
table.insert(packages, package)
end
previousI = i
goto RESETLOOP
-- Apparently "for i = 1, n" loops don't change when n changes. So when the table gets extended, packages near the end won't get picked up.
-- This is why it is needed to restart the loop.
elseif packageConfig.type == "virtual-package" then
print(("Installing virtual package %s"):format(packages[i]))
local pkgAskText = ("Select a package by typing in its number: 1) %s"):format(packageConfig.packages[1])
-- This is all a silly workaround to place commas correctly
for i = 2, #packageConfig.packages do
pkgAskText = pkgAskText .. (", %d) %s"):format(i, packageConfig.packages[i])
end
print(pkgAskText)
::RETRY::
local packageSel = terminal.read()
if not tonumber(packageSel) or tonumber(packageSel) % 1 ~= 0 then
-- Is there really no better way to check for an int..?
print("\27[93mNon-integer received - try again\27[0m")
goto RETRY
end
if tonumber(packageSel) < 1 or tonumber(packageSel) > #packageConfig.packages then
print("\27[93mInteger out of range - try again\27[0m")
end
packages[i] = packageConfig.packages[tonumber(packageSel)]
i = i - 1
goto SKIP
end
if fs.exists(("/ag2/pkg/%s.json"):format(packages[i])) then
print(("\27[93mPackage %s is already installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
end
if packageConfig.dependencies then
for _, dependency in ipairs(packageConfig.dependencies) do
table.insert(packages, i + 1, dependency)
dependencyCounter = dependencyCounter + 1
end
end
-- TODO: Add checks for conflicting packages
::SKIP::
end
elseif command == "remove" then
::JUMPBACK::
local doJumpBack = false
for i = 1, #packages do
if not fs.exists(("/ag2/pkg/%s.json"):format(packages[i])) then
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[package]
end
if source then
local packageConfig = getServersidePackageConfig(source, packages[i])
if packageConfig then
if packageConfig.type == "virtual-package" or packageConfig.type == "group" then
table.remove(packages, i)
for _, groupPackage in ipairs(packageConfig.packages) do
table.insert(packages, groupPackage)
goto GOAHEAD
end
end
end
end
print(("\27[93mPackage %s is not installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
::GOAHEAD::
end
end
-- I was originally gonna add this in the dependency cascade section, but realized it could shorten the normal dependency check code a bit
local dependencyList = {}
for _, packageConfig in ipairs(fs.list("/ag2/pkg/")) do
local package = packageConfig:sub(1, -6)
-- I'm not adding error handling here because if this fails then fuck you for touching the files by hand and good luck figuring this shit out
local _, data = getFile(("/ag2/pkg/%s.json"):format(package))
data = json.decode(data)
dependencyList[package] = data.dependencies
end
for _, package in ipairs(packages) do
if dependencyList[package] then
-- Check if all the deps are no longer needed and if they're auto-installed and stuff
for _, dependency in pairs(dependencyList[package]) do
if fs.exists(("/ag2/pkg/%s.json"):format(dependency)) then
local _, data = getFile(("/ag2/pkg/%s.json"):format(dependency))
data = json.decode(data)
if data.autoInstalled
and not table.find(packages, dependency) -- Just to prevent dependency loops and issues when re-checking the packages after jumpback
then
dependencyCounter = dependencyCounter + 1
table.insert(packages, dependency)
end
else
-- It could still be a group or a vpackage, and checking that is the job of the loop 2 loops back
table.insert(packages, dependency)
doJumpBack = true
end
end
end
end
-- Check for cascading dependencies
for packageName, dependencies in pairs(dependencyList) do
if not table.find(packages, packageName) then
for _, dependency in ipairs(dependencies) do
if table.find(packages, dependency) then
if parsed.flags.cascade or parsed.flags.C then
table.insert(packages, packageName)
dependencyCounter = dependencyCounter + 1
doJumpBack = true
-- 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\27[0m"):format(dependency, packageName))
failure = true
end
end
end
end
end
if doJumpBack then
goto JUMPBACK
-- IT'S NOT SPAGHETTI SHUT UP SHUT UP SHU
end
end
-- TODO: Add checks for the other commands
if #packages == 0 then
print("\27[93mNo packages selected.\n\27[0mExiting.")
return
end
if failure then
print("Exiting.")
return
end
if command == "install" then
if dependencyCounter == 1 then
print("\27[93m1 dependency pulled in.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d dependencies pulled in.\27[0m"):format(dependencyCounter))
end
print("Packages that will be installed:")
print(table.concat(packages, ", "))
local answer = terminal.read({prefix = "\nContinue? [Y/n] "})
if answer:lower() == "n" then
print("Exiting.")
return
end
for _, package in ipairs(packages) do
local source
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[package]
end
print(("Installing %s..."):format(package))
local _, data = getFile(fs.concat(source, "/ag2.json"))
local packageConfig = json.decode(data)[package]
if packageConfig.directories then
for _, directory in ipairs(packageConfig.directories) do
print((" Creating directory %s..."):format(directory))
fs.makeDirectory(directory)
end
end
if packageConfig.files then
for _, file in ipairs(packageConfig.files) do
::RETRY::
print((" Downloading file %s..."):format(file))
local success, data = getFile(fs.concat(source, file))
if not success then
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.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
if fs.exists(file) then
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.\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 .. "\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.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
local success, errorMessage = handle:write(data)
if not success then
handle:close()
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.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
handle:close()
::SKIP::
end
end
print(" Writing tracking file...")
if not fs.exists("/ag2/pkg/") then
fs.makeDirectory("/ag2/pkg/")
-- Technically this would break if /ag2/pkg/ was a file, but... why would it be a file?
end
-- TODO: Make functions for reading from and writing to a file with error handling since this is really repetitive
::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 .. "\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.\27[0m"):format(package))
goto SKIP
else
goto RETRY
end
end
local packageData = {
name = package,
version = packageConfig.version,
autoInstalled = false,
-- TODO: Make the above actually work
dependencies = packageConfig.dependencies,
conflicts = packageConfig.conflicts,
files = packageConfig.files,
directories = packageConfig.directories,
config = packageConfig.config
}
local trackingFile = json.encode(packageData)
local success, errorMessage = handle:write(trackingFile)
if not success then
handle:close()
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.\27[0m"):format(package))
goto SKIP
else
goto RETRY
end
else
handle:close()
end
::SKIP::
end
elseif command == "remove" then
if dependencyCounter == 1 then
print("\27[93m1 orphaned dependency will be removed.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d orphaned dependencies will be removed.\27[0m"):format(dependencyCounter))
end
print("Packages that will be removed:")
print(table.concat(packages, ", "))
local answer = terminal.read({prefix = "\nContinue? [Y/n] "})
if answer:lower() == "n" then
print("Exiting.")
return
end
for _, package in ipairs(packages) do
-- See line 263
local _, data = getFile(("/ag2/pkg/%s.json"):format(package))
data = json.decode(data)
if data.files then
for _, file in ipairs(data.files) do
print((" Removing file %s..."):format(file))
fs.remove(file) -- I cannot think of how this could fail. If you can, please add error handling here
end
end
if data.directories then
for _, directory in ipairs(data.directories) do
if fs.isDirectory(directory) then
if next(fs.list(directory)) == nil then
-- Apparently THAT's the best way to check if a table is empty in Lua. Alright I guess.
print((" Removing directory %s..."):format(directory))
fs.remove(directory)
else
print((" Directory %s specified by package %s still has something in it, skipping"):format(directory))
end
end
end
end
print(" Removing tracking file...")
fs.remove(("/ag2/pkg/%s.json"):format(package)) -- See line 500
end
end
print("Operation completed successfully.")
File diff suppressed because one or more lines are too long
-264
View File
@@ -1,264 +0,0 @@
local fs = require("filesystem")
local shell = require("shell")
local gpu = require("component").gpu
local event = require("event")
local computer = require("computer")
local ocelot = require("component").ocelot
local resX, resY = gpu.getResolution()
local textBuffer = gpu.allocateBuffer(resX, resY - 1)
local args = {...}
local file = args[1]
if not file then
print("\x1b[91mEnter a file name.")
return
end
if fs.isDirectory(file) then
print("\x1b[91mThe specified file is a directory.")
return
end
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.getWorkingDirectory(), file)
end
local data = ""
if fs.exists(file) then
local handle = fs.open(file)
local tmpdata
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
end
local lines = {}
for line in data:gmatch("[^\r\n]+") do
table.insert(lines, line)
end
local function renderText(xOffset, yOffset)
gpu.setActiveBuffer(textBuffer)
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.fill(1, 1, resX, resY - 1, " ")
for i = yOffset + 1, #lines do
gpu.set(1, i - yOffset, lines[i]:sub(xOffset + 1))
end
gpu.setActiveBuffer(0)
gpu.bitblt(0, 1, 1, resX, resY - 1, textBuffer, 1, 1)
end
local function addLine(pos)
if pos <= #lines then
for i = #lines, pos, -1 do
lines[i + 1] = lines[i]
end
lines[pos] = ""
else
table.insert(lines, "")
end
end
local function removeLine(pos)
length = #lines
for i = pos + 1, length do
lines[i - 1] = lines[i]
end
lines[length] = nil
end
-- Initialize screen
renderText(0, 0)
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(1, resY, "^X")
gpu.set(10, resY, "^S")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
gpu.set(4, resY, "Exit")
gpu.set(13, resY, "Save")
local scrollX = 0
local scrollY = 0
local cursorX = 1 -- Absolute position, not accounting for scrolling
local cursorY = 1
local cursorWhite = true
local oldTime = computer.uptime()
while true do
local renderBufferFlag = false -- Flag to render the whole text buffer
-- Handle events
local previousCursorX -- Used for blackening the previous cursor location when the cursor is moved
local previousCursorY
coroutine.yield()
local eventArgs = {}
repeat
eventArgs = {event.pull("key_down", 0)}
-- The logical solution here for flashing the cursor would be to set the timeout to 0.5, and, if the timeout is reached, change the color.
-- However, that makes scrolling freeze the screen up completely.
-- Thus, for flashing the cursor, a timer is needed.
if computer.uptime() >= oldTime + 0.5 then
oldTime = computer.uptime()
cursorWhite = not cursorWhite
end
if next(eventArgs) ~= nil then
cursorWhite = true
oldTime = computer.uptime()
end
if eventArgs[1] == "key_down" then
-- Mouse events might be added later, that's why this if statement is here
if keyboard.getCtrlDown() then
-- Special commands
if keyboard.keys[eventArgs[4]] == "x" then
goto exit
end
end
if keyboard.keys[eventArgs[4]] == "up" and cursorY > 1 then
if cursorY - scrollY <= 1 then
renderBufferFlag = true
scrollY = scrollY - 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorY = cursorY - 1
-- The cursor absolute position still has to be moved, even if on-screen it won't move
if cursorX > string.len(lines[cursorY]) + 1 then -- cursor snapping, +1 to be 1 char in front of end of line
cursorX = string.len(lines[cursorY]) + 1
end
end
if keyboard.keys[eventArgs[4]] == "down" then
if cursorY - scrollY >= resY - 1 then
renderBufferFlag = true
scrollY = scrollY + 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorY = cursorY + 1
if cursorX > string.len(lines[cursorY]) + 1 then
cursorX = string.len(lines[cursorY]) + 1
end
end
if keyboard.keys[eventArgs[4]] == "left" and cursorX > 1 then
if cursorX - scrollX <= 1 then
renderBufferFlag = true
scrollX = scrollX - 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorX = cursorX - 1
end
if keyboard.keys[eventArgs[4]] == "right" and cursorX < string.len(lines[cursorY]) + 1 then
if cursorX - scrollX >= resX then
renderBufferFlag = true
scrollX = scrollX + 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorX = cursorX + 1
end
if not keyboard.keys.special[eventArgs[4]] then
local line = lines[cursorY] or ""
line = string.sub(line, 1, cursorX - 1) .. string.char(eventArgs[3]) .. string.sub(line, cursorX, -1)
lines[cursorY] = line
cursorX = cursorX + 1
renderBufferFlag = true
end
if keyboard.keys[eventArgs[4]] == "back" then
local line = lines[cursorY]
local prevline = lines[cursorY - 1]
if cursorX > 1 then
line = string.sub(line, 1, cursorX - 2) .. string.sub(line, cursorX, -1) -- remove 1 char
elseif prevline then
prevline = prevline .. line -- copy line up to the next before removing it
ocelot.log(prevline)
line = nil
end
if line then
lines[cursorY] = line
else
removeLine(cursorY)
end
lines[cursorY - 1] = prevline
if not line then
cursorY = cursorY - 1 -- this can only trigger if the line is not the first
end
if cursorX > 1 then
cursorX = cursorX - 1
end
renderBufferFlag = true
end
if keyboard.keys[eventArgs[4]] == "enter" then
addLine(cursorY + 1)
cursorY = cursorY + 1
cursorX = 1
renderBufferFlag = true
end
end
until next(eventArgs) == nil
local displayedCursorX = cursorX - scrollX
local displayedCursorY = cursorY - scrollY
local previousDisplayedCursorX -- What a mouthful
local previousDisplayedCursorY
if previousCursorX and previousCursorY then
previousDisplayedCursorX = previousCursorX - scrollX
previousDisplayedCursorY = previousCursorY - scrollY
end
if renderBufferFlag then
renderText(scrollX, scrollY)
if cursorWhite then
-- If the cursor is black, then there's no need to do anything because there is no cursor after calling renderText().
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
-- TODO: Account for scrolling
end
else
if cursorWhite then
if previousCursorX or previousCursorY then
-- Remove old cursor
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
local letter = gpu.get(previousDisplayedCursorX, previousDisplayedCursorY)
gpu.set(previousDisplayedCursorX, previousDisplayedCursorY, letter)
end
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
else
-- If renderText() hasn't been called, the cursor may still be white and need to be turned black.
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
end
end
end
-- Cleanup
::exit::
gpu.freeBuffer(textBuffer)
gpu.setActiveBuffer(0)
terminal.clear()
-19
View File
@@ -1,19 +0,0 @@
local computer = require("computer")
local cliparse = require("cliparse")
cliparse.config({
["f"] = 1,
["frequency"] = 1,
["t"] = 1,
["time"] = 1,
})
local parsed, err = cliparse.parse(...)
if not parsed then
return print("\x1b[91m" .. err .. "\x1b[0m")
end
local freq =
tonumber(parsed.flags.f and parsed.flags.f[1] or parsed.flags.frequency and parsed.flags.frequency[1] or "440")
local time = tonumber(parsed.flags.t and parsed.flags.t[1] or parsed.flags.time and parsed.flags.time[1] or "0.1")
computer.beep(freq, time)
+1 -60
View File
@@ -1,60 +1 @@
local component = require("component")
local computer = require("computer")
local args = {...}
local force = false
local forceArgIdx = table.find(args,"-f") or table.find(args,"--force")
if forceArgIdx then
table.remove(args,forceArgIdx)
force = true
end
local function getComponentID(str)
local function fromSlot(slot)
for i,v in component.list() do
if component.slot(i)==slot then
return i
end
end
end
if str=="hdd1" or str=="#1" then return fromSlot(5) end
if str=="hdd2" or str=="#2" then return fromSlot(6) end
if str=="floppy" or str=="#3" then return fromSlot(7) end
if #str<3 then return nil,"Abbreviated ID must atleast have 3 characters" end
return component.get(str)
end
local function fileExists(compID,file)
return component.invoke(compID,"exists",file) and not component.invoke(compID,"isDirectory",file)
end
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.."\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.."\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.."\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.."\x1b[0m")
end
end
computer.setBootAddress(compID)
if computer.getBootAddress()~=compID then
return print("\x1b[91mFailed to set the boot address.\x1b[0m")
end
computer.shutdown(true)
else
require("shell").run("help boot")
end
local a=import("component")local b=import("computer")local c={...}local d=false;local e=table.find(c,"-f")or table.find(c,"--force")if e then table.remove(c,e)d=true end;local function e(b)local function c(b)for c,d in a.list()do if a.slot(c)==b then return c end end end;if b=="hdd1"or b=="#1"then return c(5)end;if b=="hdd2"or b=="#2"then return c(6)end;if b=="floppy"or b=="#3"then return c(7)end;if#b<3 then return nil,"Abbreviated ID must atleast have 3 characters"end;return a.get(b)end;local function f(b,c)return a.invoke(b,"exists",c)and not a.invoke(b,"isDirectory",c)end;if type(c[1])=="string"then local e,g=e(c[1])if not e then print("\x1b[91mCould not get component ID from '"..c[1].."'.")if type(g)=="string"then print("\x1b[91m"..g)end;return end;if not d then if componentlib.additions[e]then return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..e)end;local a=a.type(e)if a~="filesystem"and a~="drive"then return print("\x1b[91mThis component is not a storage medium.\nID: "..e)end;if a=="filesystem"and not f(e,"/init.lua")then return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..e)end end;b.setBootAddress(e)if b.getBootAddress()~=e then return print("\x1b[91mFailed to set the boot address.")end;b.shutdown(true)else shell.run("help boot")end
+1 -30
View File
@@ -1,30 +1 @@
local fs = require("filesystem")
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")
if handle == nil then
terminal.write("\27[91mCan't open " .. file .. "\27[0m\n")
goto continue
end
local enddata
while true do
local data = handle:read(math.huge or math.maxinteger)
if data == nil then break end
terminal.write(data)
enddata = data
end
handle:close()
if string.sub(enddata, -1, -1) ~= "\n" then
print("")
end
::continue::
end
local a={...}local b=import("filesystem")if not a or not a[1]then shell.run("help cat")return end;for a,a in ipairs(a)do if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")end;local a=b.open(a,"r")local b;repeat b=a:read(math.huge or math.maxinteger)termlib.write(b)until not b end
+1 -26
View File
@@ -1,26 +1 @@
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")
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 not fs.isDirectory(directory) then
terminal.write("\27[91mError: " .. directory .. ": Not a directory\27[0m\n")
return
end
shell.setWorkingDirectory(fs.canonical(directory))
local a=...local b=import("filesystem")if not a then return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)and b.isDirectory(a)then shell.workingDirectory=b.canonical(a)else print("\27[91mNo such directory.")end
+1 -3
View File
@@ -1,3 +1 @@
terminal.clear()
-- truly so much going on here
-- meow
clear()
+1 -70
View File
@@ -1,70 +1 @@
local fs = require("filesystem")
local shell = require("shell")
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
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
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.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
local a,b=...local c=import("filesystem")if not a or not b then shell.run("help cp")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")return end;if not c.exists(a)then print("\27[91mSource file does not exist.")return end;if c.exists(b)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.")return end;c.copy(a,b)
+1 -57
View File
@@ -1,57 +1 @@
local url = ...
local component = require("component")
local fs = require("filesystem")
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.\27[0m")
return
end
if not url then
print("Please enter a URL to download from.")
require("shell").run("help download")
return
end
if url:sub(-1, -1) == "/" then
url = url:sub(1, -2)
end
local internet = component.internet
local request, data, tmpdata = nil, "", nil
local status, errorMessage = pcall(function()
request = internet.request(url)
request:finishConnect()
end)
if not status then
print("\27[91mDownload failed: " .. errorMessage .. "\27[0m")
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
print("\27[91mDownload failed: " .. tostring(responseCode) .. "\27[0m")
end
repeat
tmpdata = request.read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
local saveLocation
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.\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]\27[0m"})
if answer:lower() ~= "n" then
saveLocationOK = true
end
else
saveLocationOK = true
end
until saveLocationOK
local handle = fs.open(saveLocation, "w")
handle:write(data)
handle:close()
print("File downloaded successfully.")
local a=...local b=import("component")local c=import("filesystem")if not b.list("internet")()then print("\27[91mThis program requires an internet card to run.")return end;if not a then print("Please enter a URL to download from.")shell.run("help download")return end;if a:sub(-1,-1)=="/"then a=a:sub(1,-2)end;local b=b.internet;local d,e,f=nil,"",nil;local b,g=pcall(function()d=b.request(a)d:finishConnect()end)if not b then print("\27[91mDownload failed: "..g)end;local b=d:response()if b and b~=200 then print("\27[91mDownload failed: "..tostring(b))end;repeat f=d.read(math.huge)e=e..(f or"")until not f;local b;local d=false;repeat b=read(nil,"File save location: ",c.concat(shell.workingDirectory,a:match("/([^/]+)$")))if c.isDirectory(b)then print("\27[91mThe specified location is a directory.")elseif c.exists(b)then local a=read(nil,"\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]")if a:lower()~="n"then d=true end else d=true end until d;local a=c.open(b,"w")a:write(e)a:close()print("File downloaded successfully.")
+1 -7
View File
@@ -1,7 +1 @@
local args = {...}
local concatText = args[1]
table.remove(args, 1)
for _, item in pairs(args) do
concatText = concatText .. " " .. item
end
print(concatText)
local a={...}local b=a[1]table.remove(a,1)for a,a in pairs(a)do b=b.." "..a end;print(b)
+1 -348
View File
@@ -1,348 +1 @@
local file = ...
local fs = require("filesystem")
local event = require("event")
local component = require("component")
local unicode = require("unicode")
local workingDirectory = require("shell").getWorkingDirectory()
local gpu = component.gpu
local width, height = gpu.getResolution()
local scrollPosX, scrollPosY = 1, 1
local cursorPosX, cursorPosY = 1, 1
local cursorWhite = true
local changesMade = false
local renderBuffer = gpu.allocateBuffer()
local scrollSpeed = 5
local tab = " "
--local ocelot = component.ocelot
local function rawset(x, y, text)
terminal.write("\x1b[".. tostring(y) .. ";" .. tostring(x) .. "H" .. text)
end
local filestring, filepath, handle, data, tmpdata
if file then
if file:sub(1, 1) == "/" then
filepath = file
else
filepath = workingDirectory .. file
end
handle, data, tmpdata = fs.open(filepath, "r"), "", nil
if fs.exists(filepath) then
filestring = filepath
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = {}
if data:gmatch("(.-)\n")() then
for line in data:gmatch("(.-)\n") do
local newLine = line:gsub("\r", "") -- this took me SO LONG TO FIGURE OUT AAAAAAAA I HATE CRLF I HATE CRLF I HATE CRLF
table.insert(tmpdata, newLine)
end
else
tmpdata = {data}
end
else
filepath = workingDirectory .. file
filestring = "[NEW FILE]"
tmpdata = {""}
end
else
filepath = ""
filestring = "[NEW FILE]"
tmpdata = {""}
end
local function render()
gpu.setActiveBuffer(renderBuffer)
terminal.clear()
--ocelot.log(tostring(scrollPosY))
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
for i = scrollPosY, height + scrollPosY - 3 do
gpu.set(1, i - scrollPosY + 1, (tmpdata[i] or ""):sub(scrollPosX))
end
rawset(1, height - 1, "\27[107m\27[30m" .. filestring .. string.rep(" ", width))
rawset(1, height, "\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save" .. string.rep(" ", width))
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setForeground(0)
gpu.setBackground(0xFFFFFF)
end
gpu.set(realCursorX, cursorPosY, char)
gpu.bitblt()
gpu.setActiveBuffer(0)
end
local renderFlag, cursorRenderFlag = false, false
local function scrollUp()
cursorPosY = cursorPosY - 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY < 1 then
renderFlag = true
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
renderFlag = false
scrollPosY = 1
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollDown()
cursorPosY = cursorPosY + 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY + scrollPosY - 1 > #tmpdata then
renderFlag = false
cursorPosY = #tmpdata - scrollPosY + 1
end
if cursorPosY > height - 2 then
renderFlag = true
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollLeft()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX > 1 then
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2 then
cursorPosX = cursorPosX - 1
elseif unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 > 1 then
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1
end
elseif scrollPosX > 1 then
scrollPosX = scrollPosX - 1
renderFlag = true
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollRight()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 then
cursorPosX = cursorPosX + 1
end
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
end
end
local function processEvent(args)
renderFlag, cursorRenderFlag = false, false
if args[1] == "key_down" then
local keycode = args[4]
local key = keyboard.keys[keycode]
if keyboard.getCtrlDown() then
return false, false, key
end
if key == "down" and cursorPosY < #tmpdata then
scrollDown()
end
if key == "up" then
scrollUp()
end
if key == "left" then
scrollLeft()
end
if key == "right" then
scrollRight()
end
if key == "enter" then
changesMade = true
renderFlag = true
cursorWhite = true
table.insert(tmpdata, cursorPosY + 1, tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX))
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX - 1)
cursorPosX = 1
cursorPosY = cursorPosY + 1
scrollPosX = 1
if cursorPosY > height - 2 then
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
end
if key == "back" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
if cursorPosX == 1 and cursorPosY + scrollPosY - 1 > 1 then
cursorPosY = cursorPosY - 1
if cursorPosY < 1 then
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
scrollPosY = 1
end
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2
if cursorPosX > width then
scrollPosX = cursorPosX - width + 1
cursorPosX = width
end
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1] .. tmpdata[cursorPosY + 1]
table.remove(tmpdata, cursorPosY + 1)
renderFlag = true
else
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 3) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX - 1, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) + 1)
if cursorPosX < 1 then
cursorPosX = 1
scrollPosX = scrollPosX - 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX) .. " ")
end
end
end
if key == "tab" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. tab .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = cursorPosX + unicode.wlen(tab)
if cursorPosX > width then
scrollPosX = scrollPosX + cursorPosX - width
cursorPosX = width
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
if args[3] >= 32 and args[3] <= 126 then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. unicode.char(args[3]) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1])) + 1
--ocelot.log(tostring(cursorPosX))
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
elseif args[1] == "scroll" then
if args[5] == 1 then
for i = 1, scrollSpeed do
scrollUp()
end
elseif args[5] == -1 and cursorPosY < #tmpdata then
for i = 1, scrollSpeed do
scrollDown()
end
end
end
return renderFlag, cursorRenderFlag
end
local function save()
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, string.rep(" ", width))
rawset(1, height - 1)
local savepath = terminal.read({prefix = "\27[107m\27[30mSave location: ", defaultText = filepath})
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
if fs.exists(savepath) then
gpu.set(1, height - 1, string.rep(" ", width))
local answer = terminal.read({prefix = "\27[107m\27[30mFile already exists. Overwrite it? [Y/n] "})
if answer:lower() == "n" then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
return
end
end
local handle, errorMessage = fs.open(savepath, "w")
if handle then
if table.concat(tmpdata, "\n"):sub(-1, -1) == "\n" then
handle:write(table.concat(tmpdata, "\n"))
else
handle:write(table.concat(tmpdata, "\n") .. "\n") -- add a newline at the end to follow POSIX standards
end
handle:close()
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
else
gpu.set(1, height - 1, "ERROR: " .. errorMessage:gsub("\n", "") .. string.rep(" ", width))
end
changesMade = false
end
render()
while true do
local args = {event.pull(0.5)}
local renderFlag, cursorRenderFlag, specialKey = false, false, nil
local previousCursorX, previousCursorY = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2), cursorPosY
if args and args[1] then
cursorWhite = true
renderFlag, cursorRenderFlag, specialKey = processEvent(args)
if specialKey == "x" then
if changesMade then
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()
end
end
gpu.freeAllBuffers()
terminal.clear()
return
end
if specialKey == "s" then
save()
end
repeat
args = {event.pull("key_down", 0)}
if args and args[1] then
processEvent(args)
end
until not args or not args[1]
else
cursorWhite = not cursorWhite
cursorRenderFlag = true
end
if cursorRenderFlag then
local char = gpu.get(previousCursorX, previousCursorY)
gpu.set(previousCursorX, previousCursorY, char)
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
end
gpu.set(realCursorX, cursorPosY, char)
if cursorWhite then
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0)
end
end
if renderFlag then
render()
end
end
local a=...local b=import("filesystem")local c=import("event")local d=import("component")local e=import("unicode")local d=d.gpu;local f,g=d.getResolution()local h,i=1,1;local j,k=1,1;local l=true;local m=false;local n=d.allocateBuffer()local o=5;local p=" "local function q(a,b,c)termlib.cursorPosX=a;termlib.cursorPosY=b;termlib.write(c,false)end;local r,s,t,u,v;if a then if a:sub(1,1)=="/"then s=a else s=shell.workingDirectory..a end;t,u,v=b.open(s,"r"),"",nil;if b.exists(s)then r=s;repeat v=t:read(math.huge)u=u..(v or"")until not v;v={}if u:gmatch("(.-)\n")()then for a in u:gmatch("(.-)\n")do local a=a:gsub("\r","")table.insert(v,a)end else v={u}end else s=shell.workingDirectory..a;r="[NEW FILE]"v={""}end else s=""r="[NEW FILE]"v={""}end;local function a()d.setActiveBuffer(n)clear()local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;for a=i,g+i-3 do d.set(1,a-i+1,(v[a]or""):sub(h))end;q(1,g-1,"\27[107m\27[30m"..r..string.rep(" ",f))q(1,g,"\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save"..string.rep(" ",f))local b=d.get(a,k)if l then d.setForeground(0)d.setBackground(16777215)end;d.set(a,k,b)d.bitblt()d.setActiveBuffer(0)end;local n,q=false,false;local function t()k=k-1;q=true;l=true;if k<1 then n=true;i=i-1;k=1 end;if i<1 then n=false;i=1 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function u()k=k+1;q=true;l=true;if k+i-1>#v then n=false;k=#v-i+1 end;if k>g-2 then n=true;i=i+1;k=g-2 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function w()q=true;l=true;if j>1 then if j<=e.wlen(v[k+i-1])-h+2 then j=j-1 elseif e.wlen(v[k+i-1])-h+1>1 then j=e.wlen(v[k+i-1])-h+1 end elseif h>1 then h=h-1;n=true end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function x()q=true;l=true;if j<=e.wlen(v[k+i-1])-h+1 then j=j+1 end;if j>f then j=f;h=h+1;n=true end end;local function y(a)n,q=false,false;if a[1]=="key_down"then local b=a[4]local b=keyboard.keys[b]if keyboard.ctrlDown then return false,false,b end;if b=="down"and k<#v then u()end;if b=="up"then t()end;if b=="left"then w()end;if b=="right"then x()end;if b=="enter"then m=true;n=true;l=true;table.insert(v,k+1,v[k+i-1]:sub(j))v[k+i-1]=v[k+i-1]:sub(1,j-1)j=1;k=k+1;h=1;if k>g-2 then i=i+1;k=g-2 end end;if b=="back"then m=true;q=true;l=true;if j==1 and k+i-1>1 then k=k-1;if k<1 then i=i-1;k=1 end;if i<1 then i=1 end;j=e.wlen(v[k+i-1])-h+2;if j>f then h=j-f+1;j=f end;v[k+i-1]=v[k+i-1]..v[k+1]table.remove(v,k+1)n=true else v[k+i-1]=v[k+i-1]:sub(1,j+h-3)..v[k+i-1]:sub(j+h-1)j=math.min(j-1,e.wlen(v[k+i-1])+1)if j<1 then j=1;h=h-1;n=true else d.set(1,k,v[k+i-1]:sub(h).." ")end end end;if b=="tab"then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..p..v[k+i-1]:sub(j+h-1)j=j+e.wlen(p)if j>f then h=h+j-f;j=f;n=true else d.set(1,k,v[k+i-1]:sub(h))end end;if a[3]>=32 and a[3]<=126 then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..e.char(a[3])..v[k+i-1]:sub(j+h-1)j=math.min(j,e.wlen(v[k+i-1]))+1;if j>f then j=f;h=h+1;n=true else d.set(1,k,v[k+i-1]:sub(h))end end elseif a[1]=="scroll"then if a[5]==1 then for a=1,o do t()end elseif a[5]==-1 and k<#v then for a=1,o do u()end end end;return n,q end;local function n()d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,string.rep(" ",f))termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mSave location: ",s)d.setBackground(16777215)d.setForeground(0)if b.exists(a)then d.set(1,g-1,string.rep(" ",f))local a=read(nil,"\27[107m\27[30mFile already exists. Overwrite it? [Y/n] ")if a:lower()=="n"then d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,r..string.rep(" ",f))return end end;local a,b=b.open(a,"w")if a then if table.concat(v,"\n"):sub(-1,-1)=="\n"then a:write(table.concat(v,"\n"))else a:write(table.concat(v,"\n").."\n")end;a:close()d.set(1,g-1,r..string.rep(" ",f))else d.set(1,g-1,"ERROR: "..b:gsub("\n","")..string.rep(" ",f))end;m=false end;a()while true do local b={c.pull(0.5)}local f,o,p=false,false,nil;local q,r=math.min(j,e.wlen(v[k+i-1])-h+2),k;if b and b[1]then l=true;f,o,p=y(b)if p=="x"then if m then termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mWould you like to save changes? [Y/n] ")if a:lower()~="n"then n()end end;d.freeAllBuffers()clear()return end;if p=="s"then n()end;repeat b={c.pull("key_down",0)}if b and b[1]then y(b)end until not b or not b[1]else l=not l;o=true end;if o then local a=d.get(q,r)d.set(q,r,a)local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;local b=d.get(a,k)if l then d.setBackground(16777215)d.setForeground(0)end;d.set(a,k,b)if l then d.setForeground(16777215)d.setBackground(0)end end;if f then a()end end
+1 -66
View File
@@ -1,66 +1 @@
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)
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.huge)
logo = logo .. (tmpdata or "")
until not tmpdata
handle:close()
terminal.write(logo)
terminal.write("\27[17A")
printstat("\27[92mOS\27[0m: " .. _OSVERSION)
printstat("\27[92mArchitecture\27[0m: " .. _VERSION)
local componentCounter = 0
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) .. "%")
local totalMemory = computer.totalMemory()
local usedMemory = computer.totalMemory() - computer.freeMemory()
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
return tostring(bytes) .. " B"
end
end
printstat("\27[92mMemory\27[0m: " .. formatBytes(usedMemory) .. " / " .. formatBytes(totalMemory))
local totalDisk = component.invoke(computer.getBootAddress(), "spaceTotal")
local usedDisk = component.invoke(computer.getBootAddress(), "spaceUsed")
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 ")
terminal.write("\27[5B\27[0m")
local a=import("component")local b=import("computer")local function c(a)termlib.cursorPosX=35;termlib.write(a.."\n",false)end;termlib.write(_OSLOGO,false)termlib.cursorPosY=termlib.cursorPosY-17;c("\27[92mOS\27[0m: ".._OSVERSION)c("\27[92mArchitecture\27[0m: ".._VERSION)local d=0;for a,a in a.list()do d=d+1 end;c("\27[92mComponents\27[0m: "..tostring(d))c("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList))c("\27[92mBattery\27[0m: "..tostring(math.floor(b.energy()/b.maxEnergy()*1000+0.5)/10).."%")local d=b.totalMemory()local e=b.totalMemory()-b.freeMemory()local f;if convert(d,"B","GiB")>=1 then f=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then f=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then f=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else f=tostring(d).." B"end;local d;if convert(e,"B","GiB")>=1 then d=tostring(math.floor(convert(e,"B","GiB")*100+0.5)/100).." GiB"elseif convert(e,"B","MiB")>=1 then d=tostring(math.floor(convert(e,"B","MiB")*100+0.5)/100).." MiB"elseif convert(e,"B","KiB")>=1 then d=tostring(math.floor(convert(e,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(e).." B"end;c("\27[92mMemory\27[0m: "..d.." / "..f)local d=a.invoke(b.getBootAddress(),"spaceTotal")local b=a.invoke(b.getBootAddress(),"spaceUsed")local e;if convert(d,"B","GiB")>=1 then e=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then e=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then e=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else e=tostring(d).." B"end;local d;if convert(b,"B","GiB")>=1 then d=tostring(math.floor(convert(b,"B","GiB")*100+0.5)/100).." GiB"elseif convert(b,"B","MiB")>=1 then d=tostring(math.floor(convert(b,"B","MiB")*100+0.5)/100).." MiB"elseif convert(b,"B","KiB")>=1 then d=tostring(math.floor(convert(b,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(b).." B"end;c("\27[92mDisk\27[0m: "..d.." / "..e)local a,b=a.invoke(a.list("gpu")(),"getResolution")c("\27[92mResolution\27[0m: "..tostring(a).."x"..tostring(b).."\n")c("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")c("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")termlib.cursorPosY=termlib.cursorPosY+5
+1 -268
View File
@@ -1,268 +1 @@
local fs = require("filesystem")
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
if path == "/halyde/apps/helpdb/default" then
return shell.run("cat " .. path) -- smh
end
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
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
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
local a=import("filesystem")local b={...}local c=b[1]b=nil;if not c then local a,b,c=a.open("/halyde/apps/helpdb/default.txt","r"),"",nil;repeat c=a:read(math.huge or math.maxinteger)b=b..(c or"")until not c;print(b)return end;if shell.aliases[c]then c=shell.aliases[c]end;if a.exists("/halyde/apps/helpdb/"..c..".txt")then local a,b,d=a.open("/halyde/apps/helpdb/"..c..".txt","r"),"",nil;repeat d=a:read(math.huge or math.maxinteger)b=b..(d or"")until not d;print(b)local a=table.copy(shell.aliases)if table.find(a,c)then local b=table.find(a,c)local d="Aliases:\n "..b;a[b]=nil;while table.find(a,c)do b=table.find(a,c)d=d..", "..b;a[b]=nil end;print(d)end else print("Could not find help file for: "..c..".")end
-47
View File
@@ -1,47 +0,0 @@
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.
-29
View File
@@ -1,29 +0,0 @@
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
@@ -0,0 +1,18 @@
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
@@ -1,8 +0,0 @@
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.
-23
View File
@@ -1,23 +0,0 @@
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
@@ -0,0 +1,15 @@
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
@@ -1,9 +0,0 @@
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
@@ -0,0 +1,8 @@
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
@@ -1,13 +0,0 @@
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
@@ -0,0 +1,10 @@
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
@@ -1,4 +0,0 @@
COMMAND clear
DESCRIPTION Clears the screen.
EXAMPLE1 clear
EXAMPLE1DESCRIPTION Clears the screen.
+5
View File
@@ -0,0 +1,5 @@
Usage: clear
Clears the screen.
Examples:
clear Clears the screen.
-11
View File
@@ -1,11 +0,0 @@
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
@@ -0,0 +1,11 @@
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.
-28
View File
@@ -1,28 +0,0 @@
All default Halyde shell commands:
argentum Uses the Argentum package manager.
boot Boots to another OS.
cat Concatenates and prints a file.
cd Changes directory.
clear Clears the screen.
cp Copies a file.
download Downloads a file from the internet.
echo Prints a message.
edit Opens the text editor.
fetch Displays system information.
help Shows this.
label Labels storage devices and EEPROMS.
ls Lists files.
lscor Lists coroutines.
lua Starts the Lua shell.
mkdir Makes a directory.
mv Moves/renames a file.
reboot Reboots the computer.
resolution Sets the resolution.
rm Deletes a file.
shutdown Shuts down the computer.
You can get additional information on any app or command by running:
help [COMMAND]
In the help documentation, an asterisk (*) next to an argument means it is optional.
This is excluding flags, which are all optional.
+25
View File
@@ -0,0 +1,25 @@
All default Halyde shell commands:
argentum Uses the Argentum package manager.
cat Concatenates and prints a file.
cd Changes directory.
clear Clears the screen.
cp Copies a file.
download Downloads a file from the internet.
echo Prints a message.
edit Opens the text editor.
fetch Displays system information.
help Shows this.
ls Lists files.
lscor Lists coroutines.
lua Starts the Lua shell.
mkdir Makes a directory.
mv Moves/renames a file.
reboot Reboots the computer.
rm Deletes a file.
shutdown Shuts down the computer.
You can get additional information on any app or command by running:
help [COMMAND]
In the help documentation, an asterisk (*) next to an argument means it is optional.
This is excluding flags, which are all optional.
-7
View File
@@ -1,7 +0,0 @@
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
@@ -0,0 +1,7 @@
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
@@ -1,9 +0,0 @@
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
@@ -0,0 +1,8 @@
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
@@ -1,9 +0,0 @@
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
@@ -0,0 +1,8 @@
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
@@ -1,4 +0,0 @@
COMMAND fetch
DESCRIPTION Displays system information including OS version, Lua version, memory, etc.
EXAMPLE1 fetch
EXAMPLE1DESCRIPTION Displays system information.
+5
View File
@@ -0,0 +1,5 @@
Usage: fetch
Displays system information including OS version, Lua version, memory, etc.
Examples:
fetch Displays system information.
-9
View File
@@ -1,9 +0,0 @@
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
@@ -0,0 +1,8 @@
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
@@ -1,24 +0,0 @@
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
@@ -0,0 +1,16 @@
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
@@ -1,19 +0,0 @@
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.
-11
View File
@@ -1,11 +0,0 @@
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
@@ -0,0 +1,10 @@
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
@@ -1,4 +0,0 @@
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
@@ -0,0 +1,5 @@
Usage: lscor
Lists every active coroutine by ID and name.
Examples:
lscor Lists every active coroutine by ID and name.
-37
View File
@@ -1,37 +0,0 @@
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
@@ -0,0 +1,27 @@
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
@@ -1,4 +0,0 @@
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
@@ -0,0 +1,5 @@
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
@@ -1,2 +0,0 @@
COMMAND maindrv
DESCRIPTION Shows the entire ID of the drive where Halyde is installed to.
+2
View File
@@ -0,0 +1,2 @@
Usage: maindrv
Shows the entire ID of the drive where Halyde is installed to.
-7
View File
@@ -1,7 +0,0 @@
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
@@ -0,0 +1,7 @@
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
@@ -1,11 +0,0 @@
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
@@ -0,0 +1,11 @@
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
@@ -1,4 +0,0 @@
COMMAND reboot
DESCRIPTION Reboots the computer.
EXAMPLE1 reboot
EXAMPLE1DESCRIPTION Reboots the computer.
+5
View File
@@ -0,0 +1,5 @@
Usage: reboot
Reboots the computer.
Examples:
reboot Reboots the computer.
-11
View File
@@ -1,11 +0,0 @@
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.
-7
View File
@@ -1,7 +0,0 @@
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
@@ -0,0 +1,7 @@
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.
@@ -1,3 +1,3 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFF
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFF
-4
View File
@@ -1,4 +0,0 @@
COMMAND shutdown
DESCRIPTION Shuts down the computer.
EXAMPLE1 shutdown
EXAMPLE1DESCRIPTION Shuts down the computer.
+5
View File
@@ -0,0 +1,5 @@
Usage: shutdown
Shuts down the computer.
Examples:
shutdown Shuts down the computer.
-5
View File
@@ -1,5 +0,0 @@
COMMAND touch
USAGE [FILE]...
DESCRIPTION Create an empty file.
ARG1 FILE
ARG1DESCRIPTION The path of the files to create.
+1 -92
View File
@@ -1,92 +1 @@
local component = require("component")
local computer = require("computer")
local args = {...}
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
local inputID = args[1]
local comp
local function componentFromSlot(slotNum)
if slotNum>=5 and slotNum<=8 then slotNum=slotNum-1 end
for i,v in component.list() do
if component.slot(i)==slotNum then
comp=component.proxy(i)
end
end
end
if inputID=="eeprom" then
comp = component.eeprom
elseif inputID=="halyde" then
comp = component.proxy(computer.getBootAddress())
elseif inputID:sub(1,4)=="slot" and tonumber(inputID:sub(5)) then
local slotNum = tonumber(inputID:sub(5))-1
componentFromSlot(slotNum)
elseif inputID:sub(1,1)=="#" and tonumber(inputID:sub(2)) then
local slotNum = tonumber(inputID:sub(2))+5
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.."\".\x1b[0m") end
comp = component.proxy(fullID)
else
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.."\".\x1b[0m")
end
local compID = comp.address
local function formatID(id)
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[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.."\x1b[0m")
end
local function formatLabel(label)
local res = "No label defined"
if label then res="\""..label.."\"" end
return res
end
if type(args[2])~="string" then
if not comp.getLabel then
return unsupported("getting")
end
local label
local success,reason = pcall(function()
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[0m")
else
compError("getting",reason)
end
else
if not comp.setLabel then
return unsupported("setting")
end
local newLabel = ""
for i=2,#args do
newLabel=newLabel..tostring(args[i])
if i<#args then newLabel=newLabel.." " end
end
local label
local success,reason = pcall(function()
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[0m")
else
compError("setting",reason)
end
end
local a=import("component")local b=import("computer")local c={...}if not c then return print("\x1b[91mCannot get arguments.")end;if not c[1]then return shell.run("help label")end;local d=c[1]local e;local function f(b)if b>=5 and b<=8 then b=b-1 end;for c,d in a.list()do if a.slot(c)==b then e=a.proxy(c)end end end;if d=="eeprom"then e=a.eeprom elseif d=="halyde"then e=a.proxy(b.getBootAddress())elseif d:sub(1,4)=="slot"and tonumber(d:sub(5))then local a=tonumber(d:sub(5))-1;f(a)elseif d:sub(1,1)=="#"and tonumber(d:sub(2))then local a=tonumber(d:sub(2))+5;f(a)elseif#d>=3 then local b=a.get(d)if not b then return print("\x1b[91mCould not find entire component ID from \""..d.."\".")end;e=a.proxy(b)else print("\x1b[91mAddress must have atleast 3 characters")return shell.run("help label")end;if not e then return print("\x1b[91mCould not find component from \""..d.."\".")end;local a=e.address;local function b(a)return a:sub(1,8).."\x1b[37m"..a:sub(9).."\x1b[39m"end;local function d(c)print("This \x1b[92m"..(e.type or"unknown").."\x1b[39m component doesn't support "..c.." labels.\nID: "..b(a))end;local function f(b,c)print("\x1b[91mAn error occured while "..b.." the label of this component.\nComponent: "..(a or"unknown id").." ("..((e or{}).type or"unknown type")..")\n\n"..c)end;local function g(a)local b="No label defined"if a then b="\""..a.."\""end;return b end;if type(c[2])~="string"then if not e.getLabel then return d("getting")end;local c;local d,h=pcall(function()c=e.getLabel()end)if d then print("Label of "..b(a)..((e.type and e.type~="filesystem")and" ("..e.type..")"or"")..":\n \x1b[92m"..g(c).."\x1b[39m")else f("getting",h)end else if not e.setLabel then return d("setting")end;local d=""for a=2,#c do d=d..tostring(c[a])if a<#c then d=d.." "end end;local c;local d,h=pcall(function()c=e.setLabel(d)end)if d then print("Successfully set label of "..b(a)..(e.type and" ("..e.type..")"or"").." to:\n \x1b[92m"..g(c).."\x1b[39m")else f("setting",h)end end
-110
View File
@@ -1,110 +0,0 @@
local log = require("log")
local shell = require("shell")
local fs = require("filesystem")
local args = {...}
if #args == 0 then
shell.run("help log")
return
end
local function viewlog(logname)
local logpath = "/halyde/logs/" .. logname .. ".log"
if not fs.exists(logpath) then
print("Log not found.")
return
end
local handle = fs.open(logpath)
local entry = ""
local byte
while true do
byte = handle:read(1)
if not byte then return end
if string.byte(byte) == 0x0a then --check for newline
if string.byte(string.sub(entry, -1, -1)) == 0x0d then --failsafe in case line endings are CRLF
entry = string.sub(entry, 1, -2)
else
entry = string.sub(entry, 1, -1)
end
if entry:sub(1, 4) == "WARN" then
print("\x1b[93m" .. entry .. "\x1b[0m")
elseif entry:sub(1, 5) == "ERROR" then
print("\x1b[91m" .. entry .. "\x1b[0m")
else
print(entry)
end
entry = ""
else
entry = entry .. byte
end
end
end
local function listlogs()
local files = fs.list("/halyde/logs")
local logs = {}
local j = 1
for i in ipairs(files) do
if not(string.sub(files[i], -1, -1) == "/") and string.sub(files[i], -4, -1) == ".log" then
logs[j] = string.sub(files[i], 1, -5)
j = j + 1
end
end
return logs
end
local function listlogs2()
local logs = listlogs()
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\x1b[0m")
else
print("\x1b[93m├ \x1b[0m" .. logs[i] .. "\x1b[90m.log\x1b[0m")
end
end
end
local function clearlog(logname)
if logname then
local logpath = "/halyde/logs/" .. logname .. ".log"
if not fs.exists(logpath) then
print("Log file not found.")
return
end
local success, err = fs.remove(logpath)
if not success then
print("Failed to remove log file: " .. err)
return
end
else
local logs = listlogs()
local j
for i in ipairs(logs) do
local success, err = fs.remove("/halyde/logs/" .. logs[i] .. ".log")
if not success then
print("Failed to remove log " .. logs[i] .. ": " .. err)
print("Removed" .. i - 1 .. "logs.")
return
end
j = i
end
print("Removed " .. j .. " log(s) successfully.")
end
end
if args[1] == "view" then
viewlog(args[2])
elseif args[1] == "list" then
listlogs2()
elseif args[1] == "clear" then
clearlog(args[2])
elseif args[1] == "info" or args[1] == "warn" or args[1] == "error" then
local loglevel = args[1]
local logname = args[2]
local logtext = args[3]
for i = 4, #args do
logtext = logtext .. " " .. args[i]
end
log[logname][loglevel](logtext)
end
+1 -58
View File
@@ -1,58 +1 @@
local fs = require("filesystem")
local shell = require("shell")
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 function getFileColor(name, isDir)
if isDir then return "\27[93m" end
if name:match("%.lua$") then return "\27[92m" end
return "\27[0m"
end
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
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
-- 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
local a={...}local b=a[1]a=nil;local a=import("filesystem")local c=import("unicode")local d=0;local e=2;local f={}local g={}if b then if b:sub(1,1)~="/"then b=a.concat(shell.workingDirectory,b)end else b=shell.workingDirectory end;local h=a.list(b)if h then for a,a in pairs(h)do if a:sub(-1,-1)=="/"then table.insert(f,a)a=a:sub(1,-2)else table.insert(g,a)end;if c.wlen(a)>d then d=c.wlen(a)end end;table.sort(f)table.sort(g)h={}for a,a in ipairs(f)do table.insert(h,a)end;for a,a in ipairs(g)do table.insert(h,a)end;f,g=nil,nil;for f,f in ipairs(h)do local g=false;local h;if f:sub(-1,-1)=="/"then g=true;h="\27[93m"..f:sub(1,-2)elseif f:find(".")and f:match("[^.]+$")=="lua"then h="\27[92m"..f end;h=(h or f)..string.rep(" ",d-c.wlen(f)+e)if g then print(h.." \27[0m[DIR]")else local a=a.size(a.concat(b,f))local b;if convert(a,"B","GiB")>=1 then b=tostring(math.floor(convert(a,"B","GiB")*100+0.5)/100).." GiB"elseif convert(a,"B","MiB")>=1 then b=tostring(math.floor(convert(a,"B","MiB")*100+0.5)/100).." MiB"elseif convert(a,"B","KiB")>=1 then b=tostring(math.floor(convert(a,"B","KiB")*100+0.5)/100).." KiB"else b=tostring(a).." B"end;print(h.."\27[0m"..b)end end end
+1
View File
@@ -0,0 +1 @@
print("\27[93m"..tostring(#cormgr.corList).."\27[0m coroutines active")for a=1,#cormgr.corList do if a==#cormgr.corList then print("\27[93m└ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")else print("\27[93m├ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")end end
+1 -333
View File
File diff suppressed because one or more lines are too long
-8
View File
@@ -1,8 +0,0 @@
local tasks = tsched.getTasks()
print("\27[93m"..tostring(#tasks).."\27[0m tasks active")
for i=1, #tasks do
local pipeChar = ""
if i==#tasks then pipeChar = "" end
local task = tasks[i]
print("\27[93m"..pipeChar..(task.id or i).."\27[0m - "..task.name.."\27[37m "..table.concat(task.args or {}," ").." \27[0m")
end
+1 -83
View File
@@ -1,83 +1 @@
-- terminal.readHistory["lua"] = {""}
local fs = require("filesystem")
local computer = require("computer")
local log = require("log")
local bootTime = computer.uptime()
local libList = fs.list("/lib/")
local failed = false
for _, lib in pairs(libList) do
local status, err = xpcall(function()
if lib:match("(.+)%.lua") then
local name = lib:match("(.+)%.lua")
_G[name] = require(name)
end
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\x1b[0m",
lib:match("(.+)%.lua") or lib,
firstLine or "unknown error"
)
)
log.lua.error(
string.format(
'The library located at "%s" has failed loading:\n%s',
lib,
type(err) ~= "nil" and tostring(err) or "unknown error"
)
)
failed = true
end
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[0m',
tostring(log.lua.logpath or "[unknown]")
)
)
end
print(string.format("\27[37mLoaded %d libraries in %.2f seconds\27[0m", #libList, computer.uptime() - bootTime))
print(string.format("\27[44m%s\27[0m shell", _VERSION))
print('Type "exit" to exit.')
while true do
local command = terminal.read({readHistoryType = "lua", prefix = "\27[44mlua>\27[0m "})
if command == "exit" then
coroutine.yield()
return
elseif command ~= "" then
local function runCommand()
local func, err = load("return " .. command, "=stdin")
local returns = true
if not func then
func, err = load(command, "=stdin")
returns = false
end
if not func then
return print("\x1b[91msyntax error: " .. (err or "unknown error") .. "\x1b[0m")
end
local res = { func() }
if returns then
if res and type(res[1]) ~= "nil" then
print(table.unpack(res))
elseif res and type(res[2]) ~= "nil" then
print("nil", table.unpack(res))
end
end
end
local result, reason = xpcall(runCommand, function(errMsg)
return errMsg .. "\n\n" .. debug.traceback()
end)
if not result then
print("\27[91m" .. reason .. "\27[0m")
end
end
end
print("\27[44m".._VERSION.."\27[0m shell")print('Type "exit" to exit.')termlib.readHistory["lua"]={""}local a=import("filesystem")local b=""local a=a.list("halyde/lib")for a,a in pairs(a)do if a:match("(.+)%.lua")then b=b.."local "..a:match("(.+)%.lua")..' = import("'..a:match("(.+)%.lua")..'")\n'end end;while true do local a=read("lua","\27[44mlua>\27[0m ")if a=="exit"then return else local function c()local a=load(b.."return "..a,"=stdin")or load(b..a,"=stdin")local a={assert(a)()}if a and(type(a[1])~="nil"or type(a[2])~="nil")then print(table.unpack(a))end end;local a,b=xpcall(c,function(a)return a.."\n\n"..debug.traceback()end)if not a then print("\27[91m"..b)end end end
+1 -10
View File
@@ -1,10 +1 @@
-- WTF: What the fuck is this for?? Why does it print the computer library???
-- TODO: Integrate this into lsdrv.
local computer = require("computer")
if type(computer)~="table" then
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[0m")
end
local address = computer.getBootAddress()
print(address)
local a=import("computer")if type(a)~="table"then return print("\x1b[91mComputer library returned '"..type(a).."' type\x1b[39m")end;local a=a.getBootAddress()print(a)
+1 -23
View File
@@ -1,23 +1 @@
local fs = require("filesystem")
local shell = require("shell")
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
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
local a=...local b=import("filesystem")if not a then shell.run("help mkdir")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)then print("\27[91mAn object already exists at the specified path.")end;b.makeDirectory(a)
+1 -70
View File
@@ -1,70 +1 @@
local fs = require("filesystem")
local shell = require("shell")
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
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
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
local a,b=...local c=import("filesystem")if not a or not b then shell.run("help mv")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")end;if not c.exists(a)then print("\27[91mSource file does not exist.")end;if c.exists(b)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.")return end;c.rename(a,b)
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown(true)
import("computer").shutdown(true)
-96
View File
@@ -1,96 +0,0 @@
local component = require("component")
local gpu = component.gpu
local shell = require("shell")
local args = {...}
local maxX, maxY = gpu.maxResolution()
local curX, curY = gpu.getResolution()
local function setRes()
if not(args[1] == "-x" or args[1] == "-y") then
print("\x1b[91mUnknown argument. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
return
end
local lastarg = ""
local x, y
for i = 1, 3, 2 do
if args[i] == "-x" then
if lastarg ~= "x" then
x = tonumber(args[i + 1])
lastarg = "x"
else
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
if lastarg ~= "y" then
y = tonumber(args[i + 1])
lastarg = "y"
else
print("\x1b[91mValue \"y\" was set more than once. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
return
end
end
end
if x then
if x > maxX then
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 .. "\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[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[0m to \x1b[92m" .. y .. "\x1b[0m.")
return
else
gpu.setResolution(x, y)
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 .. "\x1b[0m")
print("Maximum supported X resolution: \x1b[92m" .. maxX .. "\x1b[0m")
elseif val == "y" then
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 .. "\x1b[0m")
print("Maximum supported resolution: \x1b[92m" .. maxX .. "x" .. maxY .. "\x1b[0m")
end
end
if #args == 0 then
getRes()
return
end
if not(#args == 1) then
setRes()
return
end
local axis = args[1]
if axis == "-x" then
getRes("x")
elseif axis == "-y" then
getRes("y")
else
print("\x1b[91mUnknown argument. \x1b[0mTry running \x1b[92m\"help res\"\x1b[0m")
end
+1 -17
View File
@@ -1,17 +1 @@
local fs = require("filesystem")
local shell = require("shell")
local args = {...}
if not args[1] then
return shell.run("help rm")
end
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
end
local a=...local b=import("filesystem")if not a then shell.run("help rm")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")return end;b.remove(a)
+1 -91
View File
@@ -1,91 +1 @@
local raster = require("raster")
raster.init()
--[[for i=4,20 do
raster.set(i,i)
raster.set(i,i+4,0xFF00FF)
end]]
--[[ for x=4,20 do
for y=4,20 do
if (x+y)%2==0 then
raster.set(x,y,0xFF00FF)
end
end
end ]]
local event = require("event")
local x=0
local y=0
local vx=1
local vy=1
local col = 0x808080
local i=0
while event.pull("key_down",0)==nil do
i = i + 1
raster.set(x,y,col)
x = x + vx
y = y + vy
if x>raster.displayWidth then
x=raster.displayWidth
vx = -math.abs(vx)
col = math.random(0,0xFFFFFF)
end
if x<1 then
x=1
vx = math.abs(vx)
col = math.random(0,0xFFFFFF)
end
if y>raster.displayHeight-6 then
y=raster.displayHeight-6
vy = -math.abs(vy)
col = math.random(0,0xFFFFFF)
end
if y<1 then
y=1
vy = math.abs(vy)
col = math.random(0,0xFFFFFF)
end
if i>10 and i%15>0 then
while true do
local tries=0
local dx,dy=math.random(1,raster.displayWidth),math.random(1,raster.displayHeight-6)
if raster.get(dx,dy)~=0 then
raster.set(dx,dy,0)
break
end
tries = tries + 1
if tries>20 then
break
end
end
end
if i%10==0 then
raster.update()
coroutine.yield()
end
end
--[[ for i=0,360,4 do
local angle = i/180*math.pi
if false then
local x1,y1,x2,y2=raster.displayWidth/2,raster.displayHeight/2,raster.displayWidth/2+math.sin(angle)*80,raster.displayHeight/2+math.cos(angle)*80
raster.fillEllipse(x1,y1,x2,y2,0xFF00FF)
raster.update()
raster.fillEllipse(x1,y1,x2,y2,0x000000)
else
local x,y,c=raster.displayWidth/2,raster.displayHeight/2,math.abs(math.sin(angle)*100)
raster.drawCircle(x,y,c,0xFF00FF)
raster.update()
raster.drawCircle(x,y,c,0x000000)
end
end ]]
raster.free()
terminal.clear()
local a=import("raster")a.init()local b=import("event")local c=0;local d=0;local e=1;local f=1;local g=8421504;local h=0;while b.pull("key_down",0)==nil do h=h+1;a.set(c,d,g)c=c+e;d=d+f;if c>a.displayWidth then c=a.displayWidth;e=-math.abs(e)g=math.random(0,16777215)end;if c<1 then c=1;e=math.abs(e)g=math.random(0,16777215)end;if d>a.displayHeight-6 then d=a.displayHeight-6;f=-math.abs(f)g=math.random(0,16777215)end;if d<1 then d=1;f=math.abs(f)g=math.random(0,16777215)end;if h>10 and h%15>0 then while true do local b=0;local c,d=math.random(1,a.displayWidth),math.random(1,a.displayHeight-6)if a.get(c,d)~=0 then a.set(c,d,0)break end;b=b+1;if b>20 then break end end end;if h%10==0 then a.update()coroutine.yield()end end;a.free()termlib.cursorPosY=1
+1 -141
View File
@@ -1,141 +1 @@
local component = require("component")
local computer = require("computer")
local raster = require("raster")
local event = require("event")
-- Initialize the 3D renderer for a spinning cube
-- Using the raster library for drawing
-- Screen dimensions
local SCREEN_WIDTH, SCREEN_HEIGHT = component.invoke(component.list("gpu")(), "getResolution")
SCREEN_WIDTH, SCREEN_HEIGHT = SCREEN_WIDTH * 2, SCREEN_HEIGHT * 4
local CENTER_X = SCREEN_WIDTH / 2
local CENTER_Y = SCREEN_HEIGHT / 2
-- Cube properties
local CUBE_SIZE = 10
local increment = 0
local WHITE = 0xFFFFFF
local ROTATION_SPEED = 0.1
-- 3D cube vertices (centered at origin)
local vertices = {
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 0: left bottom back
{CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 1: right bottom back
{CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 2: right top back
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 3: left top back
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 4: left bottom front
{CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 5: right bottom front
{CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, -- 6: right top front
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} -- 7: left top front
}
-- Cube edges defined by vertex indices
local edges = {
{0, 1}, {1, 2}, {2, 3}, {3, 0}, -- back face
{4, 5}, {5, 6}, {6, 7}, {7, 4}, -- front face
{0, 4}, {1, 5}, {2, 6}, {3, 7} -- connecting edges
}
-- Projection parameters
local FOV = 256 -- Field of view (distance from camera to screen)
local Z_OFFSET = 300 -- Distance from camera to cube center
-- Initialize rotation angles
local angleX, angleY, angleZ = 0, 0, 0
-- Matrix multiplication function (apply rotation to a 3D point)
local function rotatePoint(x, y, z)
-- Rotation around X axis
local cosX, sinX = math.cos(angleX), math.sin(angleX)
local y1 = y * cosX - z * sinX
local z1 = y * sinX + z * cosX
-- Rotation around Y axis
local cosY, sinY = math.cos(angleY), math.sin(angleY)
local x1 = x * cosY + z1 * sinY
local z2 = -x * sinY + z1 * cosY
-- Rotation around Z axis
local cosZ, sinZ = math.cos(angleZ), math.sin(angleZ)
local x2 = x1 * cosZ - y1 * sinZ
local y2 = x1 * sinZ + y1 * cosZ
return x2, y2, z2
end
-- Perspective projection function (3D to 2D)
local function projectPoint(x, y, z)
-- Apply perspective projection
local scale = FOV / (z + Z_OFFSET)
local x2d = x * scale + CENTER_X
local y2d = y * scale + CENTER_Y
return x2d, y2d
end
-- Render a single frame
local function renderFrame()
local time = computer.uptime()*20
increment = time*0.05 -- increment + 0.05
CUBE_SIZE = (math.sin(increment) + 1) * 25
vertices = {
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 0: left bottom back
{CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 1: right bottom back
{CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 2: right top back
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 3: left top back
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 4: left bottom front
{CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 5: right bottom front
{CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, -- 6: right top front
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} -- 7: left top front
}
-- Update rotation angles
raster.clear()
angleX = time * ROTATION_SPEED -- angleX
angleY = time * ROTATION_SPEED * 0.7 -- angleY
angleZ = time * ROTATION_SPEED * 0.5 -- angleZ
-- Project all vertices
local projectedPoints = {}
for i, vertex in ipairs(vertices) do
-- Rotate the point
local x, y, z = rotatePoint(vertex[1], vertex[2], vertex[3])
-- Project the point to 2D
local x2d, y2d = projectPoint(x, y, z)
projectedPoints[i] = {x2d, y2d}
end
-- Draw all edges
for _, edge in ipairs(edges) do
local p1 = projectedPoints[edge[1] + 1] -- +1 because Lua indices start at 1
local p2 = projectedPoints[edge[2] + 1]
-- Draw the line
raster.drawLine(p1[1], p1[2], p2[1], p2[2], WHITE)
end
-- Render the frame
raster.update()
end
-- Main program
function main()
-- Initialize raster engine
raster.init()
-- Main loop (assume this is called repeatedly by the host environment)
while true do
renderFrame()
coroutine.yield()
if event.pull("key_down", 0) then
raster.free()
break
end
end
-- Return a reference to renderFrame so it can be called for animation
return renderFrame
end
-- Start the program
return main()
local a=import("component")local b=import("computer")local c=import("raster")local d=import("event")local a,e=a.invoke(a.list("gpu")(),"getResolution")a,e=a*2,e*4;local a=a/2;local e=e/2;local f=10;local g=0;local h=16777215;local i=0.1;local j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}local k={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}}local l=256;local m=300;local n,o,p=0,0,0;local function q(a,b,c)local d,e=math.cos(n),math.sin(n)local f=b*d-c*e;local b=b*e+c*d;local c,d=math.cos(o),math.sin(o)local e=a*c+b*d;local a=-a*d+b*c;local b,c=math.cos(p),math.sin(p)local d=e*b-f*c;local b=e*c+f*b;return d,b,a end;local function r(b,c,d)local d=l/(d+m)local a=b*d+a;local b=c*d+e;return a,b end;local function a()local a=b.uptime()*20;g=a*0.05;f=(math.sin(g)+1)*25;j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}c.clear()n=a*i;o=a*i*0.7;p=a*i*0.5;local a={}for b,c in ipairs(j)do local c,d,e=q(c[1],c[2],c[3])local c,d=r(c,d,e)a[b]={c,d}end;for b,b in ipairs(k)do local d=a[b[1]+1]local a=a[b[2]+1]c.drawLine(d[1],d[2],a[1],a[2],h)end;c.update()end;function main()c.init()while true do a()coroutine.yield()if d.pull("key_down",0)then c.free()break end end;return a end;return main()
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown()
import("computer").shutdown()
-23
View File
@@ -1,23 +0,0 @@
-- 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 fs = require("filesystem")
local shell = require("shell")
local args = {...}
if not args[1] then
return shell.run("help touch")
end
for _, file in pairs(args) do
file = shell.resolvePath(file)
local handle, err = fs.open(file, "a")
if err ~= nil then
terminal.write("\27[91mError: " .. err .. "\27[0m\n")
goto continue
end
handle:close()
::continue::
end
+1 -1
View File
@@ -1 +1 @@
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","resolution":"res"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1 -1
View File
@@ -1 +1 @@
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lstsk","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv","lscor":"lstsk"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!","Now i% more secure!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1 -1
View File
@@ -1 +1 @@
["/halyde/scripts/login.lua"]
["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/drvload.lua","/halyde/core/shell.lua"]
+1
View File
@@ -0,0 +1 @@
local a=...local b=a("/halyde/lib/filesystem.lua")(a)_G._OSVERSION="Halyde 2.8.1"_G._OSLOGO=""local c,d=b.open("/halyde/config/oslogo.ans","r"),nil;repeat d=c:read(math.huge)_OSLOGO=_OSLOGO..(d or"")until not d;_G.package={["preloaded"]={}}a("/halyde/core/datatools.lua")()function _G.import(a,...)local c=table.pack(...)if package.preloaded[a]then return package.preloaded[a]end;local d;if b.exists(a)then d=a elseif b.exists("/halyde/lib/"..a..".lua")then d="/halyde/lib/"..a..".lua"elseif shell and shell.workingDirectory and b.exists(shell.workingDirectory..a)then d=shell.workingDirectory..a end;assert(d,"module not found\npossible locations:\n/halyde/lib/"..a..".lua")local a,b,e=b.open(d),"",nil;repeat e=a:read(math.huge or math.maxinteger)b=b..(e or"")until not e;a:close()return(assert(load(b,"="..d))(table.unpack(c)))end;local function a(a)local b,c,d=assert(b.open("/halyde/lib/"..a..".lua","r")),"",nil;repeat d=b:read(math.huge or math.maxinteger)c=c..(d or"")until not d;package.preloaded[a]=assert(load(c,"="..a))()_G[a]=nil end;a("component")a("computer")a("filesystem")local a=import("component")local b=a.gpu;local a=a.list("screen")()b.bind(a)b.setResolution(b.maxResolution())local a=import("filesystem")if not a.exists("/halyde/config/shell.json")then a.copy("/halyde/config/generate/shell.json","/halyde/config/shell.json")end;if not a.exists("/halyde/config/startupapps.json")then a.copy("/halyde/config/generate/startupapps.json","/halyde/config/startupapps.json")end;a=nil;import("/halyde/core/cormgr.lua")
+1
View File
@@ -0,0 +1 @@
_G.cormgr={}_G.cormgr.corList={}_G.cormgr.labelList={}local a=import("component")local b=import("filesystem")local c=import("json")local a=a.gpu;function _G.cormgr.loadCoroutine(b,...)local c={...}local function d()local b,c=xpcall(function(...)import(...)end,function(a)return a.."\n \n"..debug.traceback()end,b,table.unpack(c))if not b then if print then a.freeAllBuffers()print("\n\27[91m"..c)else error(c)end end end;cormgr.addCoroutine(d,string.match(tostring(b),"([^/]+)%.lua$"))end;function _G.cormgr.addCoroutine(a,b)local a=coroutine.create(a)table.insert(cormgr.corList,a)table.insert(cormgr.labelList,b)return a end;function _G.cormgr.removeCoroutine(a)local a=table.find(cormgr.labelList,cor)table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)end;function handleError(a)if a==nil then error("unknown error")else error(tostring(a).."\n \n"..debug.traceback())end end;local function a()for a=1,#_G.cormgr.corList do if cormgr.corList[a]then local b,c=coroutine.resume(cormgr.corList[a])if cormgr.corList[a]then if not b then handleError(c)end;if coroutine.status(cormgr.corList[a])=="dead"then table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)a=a-1 end end end end end;local b,d,e=b.open("/halyde/config/startupapps.json","r"),"",nil;repeat e=b:read(math.huge or math.maxinteger)d=d..(e or"")until not e;b:close()for b,b in ipairs(c.decode(d))do if b~=""then _G.cormgr.loadCoroutine(b)a()end end;while true do a()if#_G.cormgr.corList==0 then computer.shutdown()end end
+1
View File
@@ -0,0 +1 @@
local a={["bytes"]={["B"]=1,["KB"]=1000,["MB"]=1000000,["GB"]=1000000000},["bibytes"]={["B"]=1,["KiB"]=1024,["MiB"]=1048576,["GiB"]=1073741824}}function table.find(a,b)for a,c in pairs(a)do if c==b then return a end end end;function table.copy(a)local b=type(a)local c;if b=='table'then c={}for a,b in next,a,nil do c[table.copy(a)]=table.copy(b)end;setmetatable(c,table.copy(getmetatable(a)))else c=a end;return c end;function convert(b,c,d)for a,a in pairs(a)do if a[d]then return b/a[d]*a[c]end end;return false,"unit does not exist"end
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b="/halyde/drivers"local c=a.list(b)local d={}local function e(f)local a=import(a.concat(b,f))table.remove(c,table.find(c,f))if a.dependencies then for a,a in pairs(a.dependencies)do if table.find(c,a)then e(a)elseif table.find(c,a..".lua")then e(a..".lua")else for b,c in pairs(d)do if c==a then e(b)end end end end end;if a.onStartup then a.onStartup()end end;for c,c in pairs(c)do local a=import(a.concat(b,c))if a.type then d[c]=a.type end end;for a,a in pairs(c)do if a:sub(-1,-1)~="/"then e(a)end end
+1
View File
@@ -0,0 +1 @@
_G.evmgr={}_G.evmgr.eventQueue={}local a=10;local b=import("computer")keyboard.ctrlDown=false;keyboard.altDown=false;keyboard.shiftDown=false;while true do local c;repeat c={b.uptime(),b.pullSignal(0)}if c and c[2]then table.insert(evmgr.eventQueue,c)if keyboard then if c[2]=="key_down"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=true elseif a=="lmenu"then keyboard.altDown=true elseif a=="lshift"then keyboard.shiftDown=true elseif a=="c"and keyboard.ctrlDown and keyboard.altDown then if print then print("\n\27[91mCoroutine "..tostring(#cormgr.corList).." killed.")end;cormgr.corList[#cormgr.corList]=nil end elseif c[2]=="key_up"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=false elseif a=="lmenu"then keyboard.altDown=false elseif a=="lshift"then keyboard.shiftDown=true end end end;while#evmgr.eventQueue>a do table.remove(evmgr.eventQueue,1)end end until not c or not c[1]coroutine.yield()end
+1
View File
@@ -0,0 +1 @@
_G.keyboard={["keys"]={}}keyboard.keys["1"]=2;keyboard.keys["2"]=3;keyboard.keys["3"]=4;keyboard.keys["4"]=5;keyboard.keys["5"]=6;keyboard.keys["6"]=7;keyboard.keys["7"]=8;keyboard.keys["8"]=9;keyboard.keys["9"]=10;keyboard.keys["0"]=11;keyboard.keys.a=30;keyboard.keys.b=48;keyboard.keys.c=46;keyboard.keys.d=32;keyboard.keys.e=18;keyboard.keys.f=33;keyboard.keys.g=34;keyboard.keys.h=35;keyboard.keys.i=23;keyboard.keys.j=36;keyboard.keys.k=37;keyboard.keys.l=38;keyboard.keys.m=50;keyboard.keys.n=49;keyboard.keys.o=24;keyboard.keys.p=25;keyboard.keys.q=16;keyboard.keys.r=19;keyboard.keys.s=31;keyboard.keys.t=20;keyboard.keys.u=22;keyboard.keys.v=47;keyboard.keys.w=17;keyboard.keys.x=45;keyboard.keys.y=21;keyboard.keys.z=44;keyboard.keys.apostrophe=40;keyboard.keys.at=145;keyboard.keys.back=14;keyboard.keys.backslash=43;keyboard.keys.capital=58;keyboard.keys.colon=146;keyboard.keys.comma=51;keyboard.keys.enter=28;keyboard.keys.equals=13;keyboard.keys.grave=41;keyboard.keys.lbracket=26;keyboard.keys.lcontrol=29;keyboard.keys.lmenu=56;keyboard.keys.lshift=42;keyboard.keys.minus=12;keyboard.keys.numlock=69;keyboard.keys.pause=197;keyboard.keys.period=52;keyboard.keys.rbracket=27;keyboard.keys.rcontrol=157;keyboard.keys.rmenu=184;keyboard.keys.rshift=54;keyboard.keys.scroll=70;keyboard.keys.semicolon=39;keyboard.keys.slash=53;keyboard.keys.space=57;keyboard.keys.stop=149;keyboard.keys.tab=15;keyboard.keys.underline=147;keyboard.keys.up=200;keyboard.keys.down=208;keyboard.keys.left=203;keyboard.keys.right=205;keyboard.keys.home=199;keyboard.keys["end"]=207;keyboard.keys.pageUp=201;keyboard.keys.pageDown=209;keyboard.keys.insert=210;keyboard.keys.delete=211;keyboard.keys.f1=59;keyboard.keys.f2=60;keyboard.keys.f3=61;keyboard.keys.f4=62;keyboard.keys.f5=63;keyboard.keys.f6=64;keyboard.keys.f7=65;keyboard.keys.f8=66;keyboard.keys.f9=67;keyboard.keys.f10=68;keyboard.keys.f11=87;keyboard.keys.f12=88;keyboard.keys.f13=100;keyboard.keys.f14=101;keyboard.keys.f15=102;keyboard.keys.f16=103;keyboard.keys.f17=104;keyboard.keys.f18=105;keyboard.keys.f19=113;keyboard.keys.kana=112;keyboard.keys.kanji=148;keyboard.keys.convert=121;keyboard.keys.noconvert=123;keyboard.keys.yen=125;keyboard.keys.circumflex=144;keyboard.keys.ax=150;keyboard.keys.numpad0=82;keyboard.keys.numpad1=79;keyboard.keys.numpad2=80;keyboard.keys.numpad3=81;keyboard.keys.numpad4=75;keyboard.keys.numpad5=76;keyboard.keys.numpad6=77;keyboard.keys.numpad7=71;keyboard.keys.numpad8=72;keyboard.keys.numpad9=73;keyboard.keys.numpadmul=55;keyboard.keys.numpaddiv=181;keyboard.keys.numpadsub=74;keyboard.keys.numpadadd=78;keyboard.keys.numpaddecimal=83;keyboard.keys.numpadcomma=179;keyboard.keys.numpadenter=156;keyboard.keys.numpadequals=141;setmetatable(keyboard.keys,{__index=function(a,b)if type(b)~="number"then return end;for a,c in pairs(a)do if c==b then return a end end end})

Some files were not shown because too many files have changed in this diff Show More