Revert pre-alpha 3.0.0 because I was supposed to push it to a branch.

This reverts commit cbf25999f0.
This commit is contained in:
WahPlus
2025-08-17 16:44:40 +03:00
parent 5276d2437b
commit 2dee5eaba7
52 changed files with 955 additions and 1232 deletions
+6 -96
View File
@@ -1,100 +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"
"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
}
}
+8 -8
View File
@@ -1,9 +1,9 @@
local packages = {...}
local command = packages[1]
table.remove(packages, 1)
local fs = require("filesystem")
local component = require("component")
local agReg = require("/argentum/registry.cfg")
local fs = import("filesystem")
local component = import("component")
local agReg = import("/argentum/registry.cfg")
if not command then
shell.run("help argentum")
return
@@ -346,7 +346,7 @@ if command == "install" then
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
agReg = import("/argentum/registry.cfg")
while true do
if not doChecks(packages[i]) then
table.insert(fails, packages[i])
@@ -497,7 +497,7 @@ elseif command == "update" then
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
agReg = import("/argentum/registry.cfg")
if not packages[1] then
local packagesInstalled = fs.list("/argentum/store/")
for _, currentPackage in pairs(packagesInstalled) do
@@ -632,7 +632,7 @@ elseif command == "info" then
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
agReg = import("/argentum/registry.cfg")
if not agReg[packages[1]] and not source then
print("\27[91mPackage " .. packages[1] .. " does not exist.")
return
@@ -656,7 +656,7 @@ elseif command == "search" then
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
agReg = import("/argentum/registry.cfg")
local searchResults = {}
for packageName, _ in pairs(agReg) do
if packageName:find(packages[1], 1, true) then
@@ -679,7 +679,7 @@ elseif command == "list" then
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
agReg = import("/argentum/registry.cfg")
local sortedPackages = {}
for packageName, _ in pairs(agReg) do
table.insert(sortedPackages, packageName)
+2 -2
View File
@@ -1,5 +1,5 @@
local component = require("component")
local computer = require("computer")
local component = import("component")
local computer = import("computer")
local args = {...}
local force = false
+1 -1
View File
@@ -1,5 +1,5 @@
local files = {...}
local fs = require("filesystem")
local fs = import("filesystem")
if not files or not files[1] then
shell.run("help cat")
return
+1 -1
View File
@@ -1,5 +1,5 @@
local directory = ...
local fs = require("filesystem")
local fs = import("filesystem")
if not directory then
return
+1 -1
View File
@@ -1,5 +1,5 @@
local fromFile, toFile = ...
local fs = require("filesystem")
local fs = import("filesystem")
if not fromFile or not toFile then
shell.run("help cp")
+2 -2
View File
@@ -1,7 +1,7 @@
local url = ...
local component = require("component")
local fs = require("filesystem")
local component = import("component")
local fs = import("filesystem")
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.")
+4 -4
View File
@@ -1,8 +1,8 @@
local file = ...
local fs = require("filesystem")
local event = require("event")
local component = require("component")
local unicode = require("unicode")
local fs = import("filesystem")
local event = import("event")
local component = import("component")
local unicode = import("unicode")
local gpu = component.gpu
local width, height = gpu.getResolution()
local scrollPosX, scrollPosY = 1, 1
+8 -8
View File
@@ -1,13 +1,13 @@
local component = require("component")
local computer = require("computer")
local component = import("component")
local computer = import("computer")
local function printstat(text)
terminal.cursorPosX = 35
terminal.write(text .. "\n", false)
termlib.cursorPosX = 35
termlib.write(text .. "\n", false)
end
terminal.write(_OSLOGO, false)
terminal.cursorPosY = terminal.cursorPosY - 17
termlib.write(_OSLOGO, false)
termlib.cursorPosY = termlib.cursorPosY - 17
printstat("\27[92mOS\27[0m: ".._OSVERSION)
printstat("\27[92mArchitecture\27[0m: ".._VERSION)
local componentCounter = 0
@@ -15,7 +15,7 @@ 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[92mCoroutines\27[0m: "..tostring(#cormgr.corList))
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()
@@ -67,4 +67,4 @@ local width, height = component.invoke(component.list("gpu")(), "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.cursorPosY = terminal.cursorPosY + 5
termlib.cursorPosY = termlib.cursorPosY + 5
+1 -1
View File
@@ -1,4 +1,4 @@
local fs = require("filesystem")
local fs = import("filesystem")
local args = {...}
local command = args[1]
args = nil
+2 -2
View File
@@ -1,5 +1,5 @@
local component = require("component")
local computer = require("computer")
local component = import("component")
local computer = import("computer")
local args = {...}
if not args then return print("\x1b[91mCannot get arguments.") end
if not args[1] then
+2 -2
View File
@@ -1,8 +1,8 @@
local args = {...}
local target = args[1]
args = nil
local fs = require("filesystem")
local unicode = require("unicode")
local fs = import("filesystem")
local unicode = import("unicode")
local maxLength = 0
local margin = 2 -- minimum space between filename and size
local dirTable = {}
+4 -4
View File
@@ -1,7 +1,7 @@
local serialize = require("serialize")
local component = require("component")
local computer = require("computer")
local unicode = require("unicode")
local serialize = import("serialize")
local component = import("component")
local computer = import("computer")
local unicode = import("unicode")
local width,height = component.gpu.getResolution()
+2 -2
View File
@@ -1,13 +1,13 @@
print("\27[44m".._VERSION.."\27[0m shell")
print('Type "exit" to exit.')
termlib.readHistory["lua"] = {""}
local fs = require("filesystem")
local fs = import("filesystem")
local loadedLibraries = ""
local libList = fs.list("halyde/lib")
for _, lib in pairs(libList) do
if lib:match("(.+)%.lua") then
loadedLibraries = loadedLibraries .. "local " .. lib:match("(.+)%.lua") .. ' = require("' .. lib:match("(.+)%.lua") .. '")\n'
loadedLibraries = loadedLibraries .. "local " .. lib:match("(.+)%.lua") .. ' = import("' .. lib:match("(.+)%.lua") .. '")\n'
end
end
+1 -1
View File
@@ -1,4 +1,4 @@
local computer = require("computer")
local computer = import("computer")
if type(computer)~="table" then
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m")
+1 -1
View File
@@ -1,5 +1,5 @@
local directory = ...
local fs = require("filesystem")
local fs = import("filesystem")
if not directory then
shell.run("help mkdir")
+1 -1
View File
@@ -1,5 +1,5 @@
local fromFile, toFile = ...
local fs = require("filesystem")
local fs = import("filesystem")
if not fromFile or not toFile then
shell.run("help mv")
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown(true)
import("computer").shutdown(true)
View File
+1 -1
View File
@@ -1,5 +1,5 @@
local file = ...
local fs = require("filesystem")
local fs = import("filesystem")
if not file then
shell.run("help rm")
+2 -2
View File
@@ -1,4 +1,4 @@
local raster = require("raster")
local raster = import("raster")
raster.init()
@@ -15,7 +15,7 @@ end]]
end
end ]]
local event = require("event")
local event = import("event")
local x=0
local y=0
local vx=1
+4 -4
View File
@@ -1,7 +1,7 @@
local component = require("component")
local computer = require("computer")
local raster = require("raster")
local event = require("event")
local component = import("component")
local computer = import("computer")
local raster = import("raster")
local event = import("event")
-- Initialize the 3D renderer for a spinning cube
-- Using the raster library for drawing
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown()
import("computer").shutdown()
+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","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!","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/shell/shell.lua"]
["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/drvload.lua","/halyde/core/shell.lua"]
+98
View File
@@ -0,0 +1,98 @@
local loadfile = ...
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
_G._OSVERSION = "Halyde 2.8.1"
_G._OSLOGO = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
tmpdata = handle:read(math.huge)
_OSLOGO = _OSLOGO .. (tmpdata or "")
until not tmpdata
_G.package = {["preloaded"] = {}}
loadfile("/halyde/core/datatools.lua")()
function _G.import(module, ...)
local args = table.pack(...)
if package.preloaded[module] then
return package.preloaded[module]
end
local modulepath
if filesystem.exists(module) then
modulepath = module
elseif filesystem.exists("/halyde/lib/"..module..".lua") then
modulepath = "/halyde/lib/"..module..".lua"
elseif shell and shell.workingDirectory and filesystem.exists(shell.workingDirectory..module) then
modulepath = shell.workingDirectory..module
end
assert(modulepath, "module not found\npossible locations:\n/halyde/lib/"..module..".lua")
local handle, data, tmpdata = filesystem.open(modulepath), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return(assert(load(data, "="..modulepath))(table.unpack(args)))
end
local function preload(module)
local handle, data, tmpdata = assert(filesystem.open("/halyde/lib/" .. module .. ".lua", "r")), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
package.preloaded[module] = assert(load(data, "="..module))()
_G[module] = nil
end
preload("component")
preload("computer")
preload("filesystem")
local component = import("component")
local gpu = component.gpu
local screenAddress = component.list("screen")()
--local screen = component.screen
gpu.bind(screenAddress)
--local maxWidth, maxHeight = gpu.maxResolution()
--local aspectX, aspectY = screen.getAspectRatio()
--local screenRatio = aspectX * 2 / aspectY
-- Calculate potential dimensions
--local widthLimited = math.floor(maxHeight * screenRatio)
--local heightLimited = math.floor(maxWidth / screenRatio)
--local targetWidth, targetHeight
--if widthLimited <= maxWidth then
-- height is the limiting factor
-- targetWidth = widthLimited
-- targetHeight = maxHeight
--else
-- width is the limiting factor
-- targetWidth = maxWidth
-- targetHeight = heightLimited
--end
--targetWidth = math.min(targetWidth, maxWidth)
--targetHeight = math.min(targetHeight, maxHeight)
--gpu.setResolution(targetWidth, targetHeight)
gpu.setResolution(gpu.maxResolution())
--local handle = assert(filesystem.open("/bazinga.txt", "w"))
--assert(handle:write("Bazinga!"))
--handle:close()
local fs = import("filesystem")
if not fs.exists("/halyde/config/shell.json") then -- Auto-generate configs
fs.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json")
end
if not fs.exists("/halyde/config/startupapps.json") then
fs.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json")
end
fs = nil
import("/halyde/core/cormgr.lua")
+97
View File
@@ -0,0 +1,97 @@
_G.cormgr = {}
_G.cormgr.corList = {}
_G.cormgr.labelList = {}
local component = import("component")
local filesystem = import("filesystem")
local json = import("json")
local gpu = component.gpu
--local ocelot = component.ocelot
function _G.cormgr.loadCoroutine(path,...)
local args = {...}
local function corFunction()
local result, errorMessage = xpcall(function(...)
import(...)
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, path, table.unpack(args))
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
--import(path, table.unpack(args))
end
cormgr.addCoroutine(corFunction, string.match(tostring(path), "([^/]+)%.lua$"))
end
function _G.cormgr.addCoroutine(func, name)
local cor = coroutine.create(func)
table.insert(cormgr.corList, cor)
table.insert(cormgr.labelList, name)
return cor
end
function _G.cormgr.removeCoroutine(name)
local index = table.find(cormgr.labelList, cor)
table.remove(cormgr.corList, index)
table.remove(cormgr.labelList, index)
--coroutine.close(cor)
end
function handleError(errormsg)
if errormsg == nil then
error("unknown error")
else
error(tostring(errormsg).."\n \n"..debug.traceback())
end
end
local function runCoroutines()
for i = 1, #_G.cormgr.corList do
if cormgr.corList[i] then
local result, errorMessage = coroutine.resume(cormgr.corList[i])
if cormgr.corList[i] then
if not result then
handleError(errorMessage)
end
if coroutine.status(cormgr.corList[i]) == "dead" then
table.remove(cormgr.corList, i)
table.remove(cormgr.labelList, i)
--ocelot.log("Removed coroutine")
i = i - 1
end
--computer.pullSignal(0)
--coroutine.yield()
end
end
end
end
local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
for _, line in ipairs(json.decode(data)) do
if line ~= "" then
--[[ if _G.print then
print(line)
end ]]
_G.cormgr.loadCoroutine(line)
runCoroutines()
end
end
-- _G.cormgr.loadCoroutine("/halyde/core/shell.lua")
while true do
runCoroutines()
if #_G.cormgr.corList == 0 then
computer.shutdown()
end
end
+46
View File
@@ -0,0 +1,46 @@
local fs = import("filesystem")
local driverPath = "/halyde/drivers"
local drivers = fs.list(driverPath)
local driverTypes = {}
local function loadDriver(drvName)
local driverData = import(fs.concat(driverPath, drvName))
table.remove(drivers, table.find(drivers, drvName))
if driverData.dependencies then
for _, dependency in pairs(driverData.dependencies) do
if table.find(drivers, dependency) then
loadDriver(dependency)
elseif table.find(drivers, dependency .. ".lua") then
loadDriver(dependency .. ".lua")
else
for typeLookupDrvName, typeLookupDrvType in pairs(driverTypes) do
if typeLookupDrvType == dependency then
loadDriver(typeLookupDrvName)
-- Don't break, because there can be multiple drivers of the correct type
end
end
end
end
end
--print(drvName)
if driverData.onStartup then -- I have no idea why would this not exist, but it's a failsafe
driverData.onStartup()
end
-- More functions to be implemented in the future
end
for _, drvName in pairs(drivers) do -- Get all the driver types
local driverData = import(fs.concat(driverPath, drvName))
if driverData.type then
--print(driverData.type)
driverTypes[drvName] = driverData.type -- Not the other way around because there can be multiple drivers of the same type, but there can't be multiple entries with the same key
end
end
for _, drvName in pairs(drivers) do -- Load the drivers
if drvName:sub(-1, -1) ~= "/" then -- Check if it's not a directory. Otherwise it might be driver config
loadDriver(drvName)
end
end
@@ -2,11 +2,11 @@ _G.evmgr = {}
_G.evmgr.eventQueue = {}
local maxEventQueueLength = 10 -- increase if events start getting dropped
local computer = require("computer")
local computer = import("computer")
_G._PUBLIC.keyboard.ctrlDown = false
_G._PUBLIC.keyboard.altDown = false
_G._PUBLIC.keyboard.shiftDown = false
keyboard.ctrlDown = false
keyboard.altDown = false
keyboard.shiftDown = false
--local ocelot = component.proxy(component.list("ocelot")())
@@ -16,31 +16,31 @@ while true do
args = {computer.uptime(), computer.pullSignal(0)}
if args and args[2] then
table.insert(evmgr.eventQueue, args)
if _PUBLIC.keyboard then
if keyboard then
if args[2] == "key_down" then
local keycode = args[5]
local key = _PUBLIC.keyboard.keys[keycode]
local key = keyboard.keys[keycode]
if key == "lcontrol" then
_PUBLIC.keyboard.ctrlDown = true
keyboard.ctrlDown = true
elseif key == "lmenu" then
_PUBLIC.keyboard.altDown = true
keyboard.altDown = true
elseif key == "lshift" then
_PUBLIC.keyboard.shiftDown = true
elseif key == "c" and _PUBLIC.keyboard.ctrlDown and _PUBLIC.keyboard.altDown then
keyboard.shiftDown = true
elseif key == "c" and keyboard.ctrlDown and keyboard.altDown then
if print then
print("\n\27[91mCoroutine "..tostring(#tsched.tasks).." killed.")
print("\n\27[91mCoroutine "..tostring(#cormgr.corList).." killed.")
end
tsched.tasks[#tsched.tasks] = nil
cormgr.corList[#cormgr.corList] = nil
end
elseif args[2] == "key_up" then
local keycode = args[5]
local key = _PUBLIC.keyboard.keys[keycode]
local key = keyboard.keys[keycode]
if key == "lcontrol" then
_PUBLIC.keyboard.ctrlDown = false
keyboard.ctrlDown = false
elseif key == "lmenu" then
_PUBLIC.keyboard.altDown = false
keyboard.altDown = false
elseif key == "lshift" then
_PUBLIC.keyboard.shiftDown = true
keyboard.shiftDown = true
end
end
end
+143
View File
@@ -0,0 +1,143 @@
_G.keyboard = {["keys"] = {}}
keyboard.keys["1"] = 0x02
keyboard.keys["2"] = 0x03
keyboard.keys["3"] = 0x04
keyboard.keys["4"] = 0x05
keyboard.keys["5"] = 0x06
keyboard.keys["6"] = 0x07
keyboard.keys["7"] = 0x08
keyboard.keys["8"] = 0x09
keyboard.keys["9"] = 0x0A
keyboard.keys["0"] = 0x0B
keyboard.keys.a = 0x1E
keyboard.keys.b = 0x30
keyboard.keys.c = 0x2E
keyboard.keys.d = 0x20
keyboard.keys.e = 0x12
keyboard.keys.f = 0x21
keyboard.keys.g = 0x22
keyboard.keys.h = 0x23
keyboard.keys.i = 0x17
keyboard.keys.j = 0x24
keyboard.keys.k = 0x25
keyboard.keys.l = 0x26
keyboard.keys.m = 0x32
keyboard.keys.n = 0x31
keyboard.keys.o = 0x18
keyboard.keys.p = 0x19
keyboard.keys.q = 0x10
keyboard.keys.r = 0x13
keyboard.keys.s = 0x1F
keyboard.keys.t = 0x14
keyboard.keys.u = 0x16
keyboard.keys.v = 0x2F
keyboard.keys.w = 0x11
keyboard.keys.x = 0x2D
keyboard.keys.y = 0x15
keyboard.keys.z = 0x2C
keyboard.keys.apostrophe = 0x28
keyboard.keys.at = 0x91
keyboard.keys.back = 0x0E -- backspace
keyboard.keys.backslash = 0x2B
keyboard.keys.capital = 0x3A -- capslock
keyboard.keys.colon = 0x92
keyboard.keys.comma = 0x33
keyboard.keys.enter = 0x1C
keyboard.keys.equals = 0x0D
keyboard.keys.grave = 0x29 -- accent grave
keyboard.keys.lbracket = 0x1A
keyboard.keys.lcontrol = 0x1D
keyboard.keys.lmenu = 0x38 -- left Alt
keyboard.keys.lshift = 0x2A
keyboard.keys.minus = 0x0C
keyboard.keys.numlock = 0x45
keyboard.keys.pause = 0xC5
keyboard.keys.period = 0x34
keyboard.keys.rbracket = 0x1B
keyboard.keys.rcontrol = 0x9D
keyboard.keys.rmenu = 0xB8 -- right Alt
keyboard.keys.rshift = 0x36
keyboard.keys.scroll = 0x46 -- Scroll Lock
keyboard.keys.semicolon = 0x27
keyboard.keys.slash = 0x35 -- / on main keyboard
keyboard.keys.space = 0x39
keyboard.keys.stop = 0x95
keyboard.keys.tab = 0x0F
keyboard.keys.underline = 0x93
-- Keypad (and numpad with numlock off)
keyboard.keys.up = 0xC8
keyboard.keys.down = 0xD0
keyboard.keys.left = 0xCB
keyboard.keys.right = 0xCD
keyboard.keys.home = 0xC7
keyboard.keys["end"] = 0xCF
keyboard.keys.pageUp = 0xC9
keyboard.keys.pageDown = 0xD1
keyboard.keys.insert = 0xD2
keyboard.keys.delete = 0xD3
-- Function keys
keyboard.keys.f1 = 0x3B
keyboard.keys.f2 = 0x3C
keyboard.keys.f3 = 0x3D
keyboard.keys.f4 = 0x3E
keyboard.keys.f5 = 0x3F
keyboard.keys.f6 = 0x40
keyboard.keys.f7 = 0x41
keyboard.keys.f8 = 0x42
keyboard.keys.f9 = 0x43
keyboard.keys.f10 = 0x44
keyboard.keys.f11 = 0x57
keyboard.keys.f12 = 0x58
keyboard.keys.f13 = 0x64
keyboard.keys.f14 = 0x65
keyboard.keys.f15 = 0x66
keyboard.keys.f16 = 0x67
keyboard.keys.f17 = 0x68
keyboard.keys.f18 = 0x69
keyboard.keys.f19 = 0x71
-- Japanese keyboards
keyboard.keys.kana = 0x70
keyboard.keys.kanji = 0x94
keyboard.keys.convert = 0x79
keyboard.keys.noconvert = 0x7B
keyboard.keys.yen = 0x7D
keyboard.keys.circumflex = 0x90
keyboard.keys.ax = 0x96
-- Numpad
keyboard.keys.numpad0 = 0x52
keyboard.keys.numpad1 = 0x4F
keyboard.keys.numpad2 = 0x50
keyboard.keys.numpad3 = 0x51
keyboard.keys.numpad4 = 0x4B
keyboard.keys.numpad5 = 0x4C
keyboard.keys.numpad6 = 0x4D
keyboard.keys.numpad7 = 0x47
keyboard.keys.numpad8 = 0x48
keyboard.keys.numpad9 = 0x49
keyboard.keys.numpadmul = 0x37
keyboard.keys.numpaddiv = 0xB5
keyboard.keys.numpadsub = 0x4A
keyboard.keys.numpadadd = 0x4E
keyboard.keys.numpaddecimal = 0x53
keyboard.keys.numpadcomma = 0xB3
keyboard.keys.numpadenter = 0x9C
keyboard.keys.numpadequals = 0x8D
-- Create inverse mapping for name lookup.
setmetatable(keyboard.keys,
{
__index = function(tbl, k)
if type(k) ~= "number" then return end
for name,value in pairs(tbl) do
if value == k then
return name
end
end
end
})
@@ -1,5 +1,5 @@
local fs = require("filesystem")
local json = require("json")
local fs = import("filesystem")
local json = import("json")
local handle, data, tmpdata = fs.open("/halyde/config/shell.json", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
@@ -7,21 +7,23 @@ repeat
until not tmpdata
handle:close()
local shellcfg = json.decode(data)
local component = require("component")
import("/halyde/core/termlib.lua")
local event = import("event")
local component = import("component")
local gpu = component.gpu
_G.shell = {}
_G.shell.workingDirectory = shellcfg["defaultWorkingDirectory"]
_G.shell.aliases = shellcfg["aliases"]
local function runAsTask(path, ...)
local function runAsCoroutine(path, ...)
--ocelot.log("running " .. path .. " as coroutine")
tsched.runAsTask(path, ...)
local corIndex = #tsched.getTasks()
local task = tsched.getTasks()[#tsched.getTasks()]
cormgr.loadCoroutine(path, ...)
local corIndex = #cormgr.corList
local cor = cormgr.corList[#cormgr.corList]
repeat
coroutine.yield()
until tsched.getTasks()[corIndex] ~= task
until cormgr.corList[corIndex] ~= cor
end
function _G.shell.run(command)
@@ -64,14 +66,14 @@ function _G.shell.run(command)
if fs.exists(args[1]) and not fs.isDirectory(args[1]) then
local path = args[1]
table.remove(args, 1)
runAsTask(path, table.unpack(args))
runAsCoroutine(path, table.unpack(args))
return
end
for _, item in pairs(PATH) do
if fs.exists(item..args[1]) and not fs.isDirectory(item .. args[1]) then
local path = fs.concat(item, args[1])
table.remove(args, 1)
runAsTask(path, table.unpack(args))
runAsCoroutine(path, table.unpack(args))
return
else -- try to look for it without the file extension
local files = fs.list(item) or {}
@@ -79,7 +81,7 @@ function _G.shell.run(command)
-- previous pattern: (.+)%.[^%.]+$
if args[1] == file:match("(.+)%.[^%.]+$") and not fs.isDirectory(item .. file) then
table.remove(args, 1)
runAsTask(item .. file, table.unpack(args))
runAsCoroutine(item .. file, table.unpack(args))
return
end
end
@@ -98,7 +100,7 @@ while true do
if shell.workingDirectory:sub(-1, -1) ~= "/" then
shell.workingDirectory = shell.workingDirectory .. "/"
end
local shellCommand = terminal.read("shell", shellcfg.prompt:format(shell.workingDirectory))
local shellCommand = read("shell", shellcfg.prompt:format(shell.workingDirectory))
shell.run(shellCommand)
gpu.freeAllBuffers()
end
+453
View File
@@ -0,0 +1,453 @@
local serialize = import("serialize")
local unicode = import("unicode")
local event = import("event")
--local keyboard = import("keyboard")
--local ocelot = component.proxy(component.list("ocelot")())
local component = import("component")
local computer = import("computer")
local gpu = component.gpu
_G.termlib = {}
termlib.cursorPosX = 1
termlib.cursorPosY = 1
termlib.readHistory = {}
local width, height = gpu.getResolution()
local ANSIColorPalette = {
["dark"] = {
[0] = 0x000000,
[1] = 0x800000,
[2] = 0x008000,
[3] = 0x808000,
[4] = 0x000080,
[5] = 0x800080,
[6] = 0x008080,
[7] = 0xC0C0C0
},
["bright"] = {
[0] = 0x808080,
[1] = 0xFF0000,
[2] = 0x00FF00,
[3] = 0xFFFF00,
[4] = 0x0000FF,
[5] = 0xFF00FF,
[6] = 0x00FFFF,
[7] = 0xFFFFFF
}
}
defaultForegroundColor = ANSIColorPalette["bright"][7]
defaultBackgroundColor = ANSIColorPalette["dark"][0]
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
local function scrollDown()
local width, height = gpu.getResolution()
if gpu.copy(1,1,width,height,0,-1) then
local prevForeground = gpu.getForeground()
local prevBackground = gpu.getBackground()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1, height, width, 1, " ")
gpu.setForeground(prevForeground)
gpu.setBackground(prevBackground)
termlib.cursorPosY=height
end
end
local function newLine()
termlib.cursorPosX=1
termlib.cursorPosY = termlib.cursorPosY + 1
if termlib.cursorPosY>height then
scrollDown()
end
end
local function parseCodeNumbers(code)
local o = {}
for num in code:sub(3,-2):gmatch("[^;]+") do
table.insert(o,tonumber(num))
end
return o
end
local function from8BitColor(num)
num=math.floor(num)&255
if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end
if num>=232 then return 0x10101*(8+(num-232)*10) end
num=num-16
local palette = {0,95,135,175,215,255}
return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1]
end
local function from24BitColor(r,g,b)
r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255
return (r<<16)|(g<<8)|b
end
local function findCodeEnd(text,i)
local function inRange(v,min,max)
return v>=min and v<=max
end
i=i+2
while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
return i
end
function termlib.write(text, textWrap)
local width, height = gpu.getResolution()
-- you don't know how tiring this was just for ANSI escape code support
if textWrap == nil then
textWrap = true
end
if not text or not tostring(text) then
return
end
if text:find("\a") then
computer.beep()
end
text = tostring(text)
text = "\27[0m" .. text:gsub("\t", " ")
local readBreak = 0
-- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character.
-- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done.
local section = ""
local function printSection()
if #section==0 then
return
end
while true do
gpu.set(termlib.cursorPosX,termlib.cursorPosY,section)
if unicode.wlen(section) > width - termlib.cursorPosX + 1 and textWrap then
section = section:sub(width - termlib.cursorPosX + 2)
newLine()
else
termlib.cursorPosX = termlib.cursorPosX+unicode.wlen(section)
break
end
end
section = ""
end
for i=1,#text do
if readBreak>0 then
readBreak = readBreak - 1
goto continue
end
if string.byte(text,i)==10 then
printSection()
newLine()
elseif string.byte(text,i)==13 then
printSection()
termlib.cursorPosX=1
elseif string.byte(text,i)==0x1b and i<=#text-2 then
printSection()
--ocelot.log("0x1b char detected")
local codeType = string.sub(text,i+1,i+1)
if codeType=="[" then
-- Control Sequence Introducer
--ocelot.log("Control Sequence Introducer")
local codeEndIdx = findCodeEnd(text,i)
-- codeEndIdx = string.find(text,"m",i)
local code = string.sub(text,i,codeEndIdx)
--ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")")
readBreak = readBreak + #code - 1
local nums = parseCodeNumbers(code)
local codeEnd = code:sub(-1)
--ocelot.log("Code end: "..codeEnd..", "..#codeEnd)
if codeEnd == "m" then
-- Select Graphic Rendition
--ocelot.log("Select Graphic Rendition, ID "..nums[1])
if nums[1]>=30 and nums[1]<=37 then
gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==38 and nums[2]==5 then
gpu.setForeground(from8BitColor(nums[3]))
end
if nums[1]==38 and nums[2]==2 then
gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==39 or nums[1]==0 then
gpu.setForeground(defaultForegroundColor)
end
if nums[1]>=40 and nums[1]<=47 then
gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==48 and nums[2]==5 then
gpu.setBackground(from8BitColor(nums[3]))
end
if nums[1]==48 and nums[2]==2 then
gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==49 or nums[1]==0 then
gpu.setBackground(defaultBackgroundColor)
end
if nums[1]>=90 and nums[1]<=97 then
gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10])
end
if nums[1]>=100 and nums[1]<=107 then
gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10])
end
end
end
else
--gpu.set(termlib.cursorPosX,termlib.cursorPosY,string.sub(text,i,i))
section = section..string.sub(text,i,i)
end
::continue::
end
printSection()
end
function _G.print(...)
local args = {...}
local stringArgs = {}
for _, arg in pairs(args) do
if type(arg)=="table" then
table.insert(stringArgs, serialize.table(arg,true))
elseif tostring(arg) then
table.insert(stringArgs, tostring(arg))
end
end
termlib.write(table.concat(stringArgs, " ") .. "\n")
end
function _G.clear()
width, height = gpu.getResolution()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1,1,width,height," ")
termlib.cursorPosX, termlib.cursorPosY = 1, 1
end
function _G.read(readHistoryType, prefix, defaultText, maxChars)
checkArg(1, readHistoryType, "string", "nil")
checkArg(2, prefix, "string", "nil")
checkArg(3, defaultText, "string", "nil")
checkArg(4, maxChars, "number", "nil")
maxChars = maxChars or math.huge
local text = defaultText or ""
local historyIdx
if readHistoryType then
if not termlib.readHistory[readHistoryType] then
termlib.readHistory[readHistoryType] = {text}
elseif termlib.readHistory[readHistoryType][#termlib.readHistory[readHistoryType] ] ~= "" then
table.insert(termlib.readHistory[readHistoryType], text)
end
historyIdx = #termlib.readHistory[readHistoryType]
end
local function updateHistory()
if not readHistoryType then return end
termlib.readHistory[readHistoryType][historyIdx]=text
end
local cur = unicode.len(text)+1
if prefix then termlib.write(prefix) end
local startX, startY = termlib.cursorPosX, termlib.cursorPosY
local fg, bg = gpu.getForeground(), gpu.getBackground()
local cursorBlink = true
local function get(idx)
idx=startX+idx-1
return gpu.get(idx%width,startY+(idx//width))
end
local function checkScroll(y)
for i=1,y-height do
scrollDown()
startY=startY-1
end
return math.min(y,height)
end
local function set(idx,chr,rev)
if chr==nil or chr=="" then return end
if rev then
gpu.setForeground(bg)
gpu.setBackground(fg)
else
gpu.setForeground(fg)
gpu.setBackground(bg)
end
idx=startX+idx-1
local setX, setY = (idx-1)%width+1, startY+((idx-1)//width+1)-1
setY = checkScroll(setY)
gpu.set(setX,setY,unicode.sub(chr,1,width-setX+1))
for i=1,math.ceil((#chr+setX-1)/width)+1 do
gpu.set(1,setY+i,unicode.sub(chr,2-setX+i*width,width+i*width-setX))
setY = checkScroll(setY)
end
end
local function strDef(a,b)
if #a==0 then return b end
return a
end
local function curPos(cur)
return unicode.wlen(unicode.sub(text,1,cur-1))+1
end
local function add(chr)
if type(chr)~="string" or #chr==0 then return end
if unicode.len(text)>=maxChars then return end
if maxChars<math.huge then
chr=unicode.sub(chr,1,maxChars-unicode.len(text))
end
text=unicode.sub(text,1,cur-1)..chr..unicode.sub(text,cur)
set(curPos(cur),chr,false)
cur=math.min(cur+unicode.len(chr),maxChars+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur+1),unicode.sub(text,cur+1),false)
end
local function moveCur(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=math.max(math.min(cur+dir,unicode.len(text)+1),1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function isLetter(chr)
return not string.find("\x09 :@-./_~?&=%+#",chr,1,true)
end
local function nextCur(dir,chr,icur)
if icur==nil then icur=cur end
local next = math.max(math.min(icur+dir,unicode.len(text)+1),1)
if chr then return unicode.sub(text,next,next) end
return next
end
local function curAfterWord(dir)
local ncur = cur
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==1) do
ncur=nextCur(dir,false,ncur)
end
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==-1) do
ncur=nextCur(dir,false,ncur)
end
return ncur
end
local function moveWord(dir)
if nextCur(dir)==cur then return end
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=curAfterWord(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function deleteWord(dir)
local after = curAfterWord(dir)
local lenb = unicode.wlen(text)
if dir==1 then
text=unicode.sub(text,1,cur-1)..unicode.sub(text,after)
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
else
text = unicode.sub(text,1,after-1)..unicode.sub(text,cur)
cur=after
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
end
updateHistory()
cursorBlink = true
end
local function isLine(chr)
return chr=="\n" or chr=="\r"
end
--[[ gpu.set(startX,startY,unicode.sub(text,1,width-startX))
for i=1,(#text+startX)//width-1 do
gpu.set(startX,startY+i,unicode.sub(text,1+i*width,width-startX+i*width))
end ]]
set(1,text,false)
set(curPos(cur)," ",true)
local function reprint(new)
set(1,new..string.rep(" ",unicode.wlen(text)-unicode.wlen(new)+1),false)
cur=unicode.len(new)+1
text=new
set(curPos(cur)," ",true)
end
while true do
local args = {event.pull("key_down", "clipboard", 0.5)}
if args and args[1] == "key_down" and args[4] then
local key = keyboard.keys[args[4]]
if key=="up" and readHistoryType then
historyIdx=math.max(historyIdx-1,1)
reprint(termlib.readHistory[readHistoryType][historyIdx])
elseif key=="down" and readHistoryType then
historyIdx=math.min(historyIdx+1,#termlib.readHistory[readHistoryType])
reprint(termlib.readHistory[readHistoryType][historyIdx])
elseif key=="left" and keyboard.ctrlDown then
moveWord(-1)
elseif key=="right" and keyboard.ctrlDown then
moveWord(1)
elseif key=="left" then
moveCur(-1)
elseif key=="right" then
moveCur(1)
elseif key=="home" then
moveCur(-math.huge)
elseif key=="end" then
moveCur(math.huge)
elseif key=="back" and keyboard.ctrlDown then
deleteWord(-1)
elseif key=="delete" and keyboard.ctrlDown then
deleteWord(1)
elseif key=="back" and cur>1 then
text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur)
cur=cur-1
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur)+1,unicode.sub(text,cur+1).." ",false)
updateHistory()
elseif key=="delete" then
text = unicode.sub(text,1,cur-1)..unicode.sub(text,cur+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
if cur<=unicode.len(text) then
set(curPos(cur+1),unicode.sub(text,cur+1).." ",false)
end
updateHistory()
elseif key=="enter" then
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
break
elseif not (args[3]<32 or (args[3]>0x7F and args[3]<=0x9F)) then
add(unicode.char(args[3]) or " ")
updateHistory()
end
elseif args and args[1]=="clipboard" then
local clip = args[3]
if not args[3] then goto continue end
while isLine(unicode.sub(clip,1,1)) do clip=unicode.sub(clip,2) end
while isLine(unicode.sub(clip,-1)) do clip=unicode.sub(clip,1,-2) end
add(clip)
updateHistory()
else
cursorBlink=not cursorBlink
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),cursorBlink)
end
::continue::
end
if readHistoryType then
if termlib.readHistory[readHistoryType][#termlib.readHistory[readHistoryType]]=="" then
table.remove(termlib.readHistory[readHistoryType],#termlib.readHistory[readHistoryType])
end
if historyIdx<#termlib.readHistory[readHistoryType] then
table.remove(termlib.readHistory[readHistoryType],historyIdx)
table.insert(termlib.readHistory[readHistoryType],text)
end
while #termlib.readHistory[readHistoryType] > 50 do
table.remove(termlib.readHistory[readHistoryType], 1)
end
end
termlib.cursorPosX=1
termlib.cursorPosY=termlib.cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width)
if termlib.cursorPosY>height then scrollDown() end
return text
end
-73
View File
@@ -1,73 +0,0 @@
local loadfile = ...
local filesystem = assert(loadfile("/lib/filesystem.lua")(loadfile))
_G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file
_G._OSLOGO = ""
_G._PUBLIC = {}
local ocelot = component.proxy(component.list("ocelot")())
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
tmpdata = handle:read(math.huge)
_OSLOGO = _OSLOGO .. (tmpdata or "")
until not tmpdata
_G.package = {["preloaded"] = {}}
loadfile("/halyde/kernel/modules/datatools.lua")()
function _G.require(module, ...)
ocelot.log("Requiring " .. module)
local args = table.pack(...)
if package.preloaded[module] then
return package.preloaded[module]
end
local modulepath
if filesystem.exists(module) then
modulepath = module
elseif filesystem.exists("/lib/" .. module .. ".lua") then
modulepath = "/lib/" .. module .. ".lua"
elseif shell and shell.workingDirectory and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua")) then
modulepath = shell.workingDirectory .. module .. ".lua"
end
assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua")
local handle, data, tmpdata = filesystem.open(modulepath), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return(assert(load(data, "="..modulepath))(table.unpack(args)))
end
function _G.package.preload(module)
local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
package.preloaded[module] = assert(load(data, "="..module))()
_G[module] = nil
end
require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools.
require("/halyde/kernel/modload.lua")
package.preload("component")
package.preload("computer")
local component = require("component")
local gpu = component.gpu
local screenAddress = component.list("screen")()
gpu.bind(screenAddress)
gpu.setResolution(gpu.maxResolution())
if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs
filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json")
end
if not filesystem.exists("/halyde/config/startupapps.json") then
filesystem.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json")
end
require("/halyde/kernel/tsched.lua")
-53
View File
@@ -1,53 +0,0 @@
local fs = require("filesystem")
local ocelot = require("component").ocelot
local modulePath = "/halyde/kernel/modules"
local modules = fs.list(modulePath)
local moduleTypes = {}
local function loadModule(modName)
ocelot.log("Checking module " .. modName)
local moduleData = require(fs.concat(modulePath, modName))
table.remove(modules, table.find(modules, modName))
if not moduleData.check() then
return
end
ocelot.log("Loading module " .. modName)
if moduleData.dependencies then
for _, dependency in pairs(moduleData.dependencies) do
if table.find(modules, dependency) then
loadModule(dependency)
elseif table.find(modules, dependency .. ".lua") then
loadModule(dependency .. ".lua")
else
for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do
if typeLookupDrvType == dependency then
loadModule(typeLookupDrvName)
-- Don't break, because there can be multiple modules of the correct type
end
end
end
end
end
--print(modName)
if moduleData.init then -- I have no idea why this would not exist, but it's a failsafe
moduleData.init()
end
end
for _, modName in pairs(modules) do -- Get all the module types
local moduleData = require(fs.concat(modulePath, modName))
if moduleData.type then
--print(moduleData.type)
moduleTypes[modName] = moduleData.type -- Not the other way around because there can be multiple modules of the same type, but there can't be multiple entries with the same key
end
end
while modules[1] do
if modules[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config
loadModule(modules[1])
end
end
ocelot.log("Finished loading modules!")
-53
View File
@@ -1,53 +0,0 @@
local module = {}
module.dependencies = {"terminal"}
function module.check()
return true -- This module should always be loaded
end
function module.init()
local publicTable = {
"print",
"require",
"_VERSION",
"_OSVERSION",
"assert",
"error",
"getmetatable",
"ipairs",
"load",
"next",
"pairs",
"pcall",
"rawequal",
"rawget",
"rawlen",
"rawset",
"select",
"setmetatable",
"tonumber",
"tostring",
"type",
"xpcall",
"bit32",
"coroutine",
"debug",
"math",
"os",
"string",
"table",
"checkArg",
"utf8",
"convert"
}
for _, value in ipairs(publicTable) do
_G._PUBLIC[value] = table.copy(_G[value])
end
end
function module.exit()
_G._PUBLIC = nil
end
return module
-15
View File
@@ -1,15 +0,0 @@
local module = {}
function module.check()
return true -- This module should always be loaded
end
function module.init()
end
function module.exit()
end
return module
-157
View File
@@ -1,157 +0,0 @@
local module = {}
function module.check()
return true -- This module should always be loaded
end
function module.init()
_G._PUBLIC.keyboard = {["keys"] = {}}
_PUBLIC.keyboard.keys["1"] = 0x02
_PUBLIC.keyboard.keys["2"] = 0x03
_PUBLIC.keyboard.keys["3"] = 0x04
_PUBLIC.keyboard.keys["4"] = 0x05
_PUBLIC.keyboard.keys["5"] = 0x06
_PUBLIC.keyboard.keys["6"] = 0x07
_PUBLIC.keyboard.keys["7"] = 0x08
_PUBLIC.keyboard.keys["8"] = 0x09
_PUBLIC.keyboard.keys["9"] = 0x0A
_PUBLIC.keyboard.keys["0"] = 0x0B
_PUBLIC.keyboard.keys.a = 0x1E
_PUBLIC.keyboard.keys.b = 0x30
_PUBLIC.keyboard.keys.c = 0x2E
_PUBLIC.keyboard.keys.d = 0x20
_PUBLIC.keyboard.keys.e = 0x12
_PUBLIC.keyboard.keys.f = 0x21
_PUBLIC.keyboard.keys.g = 0x22
_PUBLIC.keyboard.keys.h = 0x23
_PUBLIC.keyboard.keys.i = 0x17
_PUBLIC.keyboard.keys.j = 0x24
_PUBLIC.keyboard.keys.k = 0x25
_PUBLIC.keyboard.keys.l = 0x26
_PUBLIC.keyboard.keys.m = 0x32
_PUBLIC.keyboard.keys.n = 0x31
_PUBLIC.keyboard.keys.o = 0x18
_PUBLIC.keyboard.keys.p = 0x19
_PUBLIC.keyboard.keys.q = 0x10
_PUBLIC.keyboard.keys.r = 0x13
_PUBLIC.keyboard.keys.s = 0x1F
_PUBLIC.keyboard.keys.t = 0x14
_PUBLIC.keyboard.keys.u = 0x16
_PUBLIC.keyboard.keys.v = 0x2F
_PUBLIC.keyboard.keys.w = 0x11
_PUBLIC.keyboard.keys.x = 0x2D
_PUBLIC.keyboard.keys.y = 0x15
_PUBLIC.keyboard.keys.z = 0x2C
_PUBLIC.keyboard.keys.apostrophe = 0x28
_PUBLIC.keyboard.keys.at = 0x91
_PUBLIC.keyboard.keys.back = 0x0E -- backspace
_PUBLIC.keyboard.keys.backslash = 0x2B
_PUBLIC.keyboard.keys.capital = 0x3A -- capslock
_PUBLIC.keyboard.keys.colon = 0x92
_PUBLIC.keyboard.keys.comma = 0x33
_PUBLIC.keyboard.keys.enter = 0x1C
_PUBLIC.keyboard.keys.equals = 0x0D
_PUBLIC.keyboard.keys.grave = 0x29 -- accent grave
_PUBLIC.keyboard.keys.lbracket = 0x1A
_PUBLIC.keyboard.keys.lcontrol = 0x1D
_PUBLIC.keyboard.keys.lmenu = 0x38 -- left Alt
_PUBLIC.keyboard.keys.lshift = 0x2A
_PUBLIC.keyboard.keys.minus = 0x0C
_PUBLIC.keyboard.keys.numlock = 0x45
_PUBLIC.keyboard.keys.pause = 0xC5
_PUBLIC.keyboard.keys.period = 0x34
_PUBLIC.keyboard.keys.rbracket = 0x1B
_PUBLIC.keyboard.keys.rcontrol = 0x9D
_PUBLIC.keyboard.keys.rmenu = 0xB8 -- right Alt
_PUBLIC.keyboard.keys.rshift = 0x36
_PUBLIC.keyboard.keys.scroll = 0x46 -- Scroll Lock
_PUBLIC.keyboard.keys.semicolon = 0x27
_PUBLIC.keyboard.keys.slash = 0x35 -- / on main _PUBLIC.keyboard
_PUBLIC.keyboard.keys.space = 0x39
_PUBLIC.keyboard.keys.stop = 0x95
_PUBLIC.keyboard.keys.tab = 0x0F
_PUBLIC.keyboard.keys.underline = 0x93
-- Keypad (and numpad with numlock off)
_PUBLIC.keyboard.keys.up = 0xC8
_PUBLIC.keyboard.keys.down = 0xD0
_PUBLIC.keyboard.keys.left = 0xCB
_PUBLIC.keyboard.keys.right = 0xCD
_PUBLIC.keyboard.keys.home = 0xC7
_PUBLIC.keyboard.keys["end"] = 0xCF
_PUBLIC.keyboard.keys.pageUp = 0xC9
_PUBLIC.keyboard.keys.pageDown = 0xD1
_PUBLIC.keyboard.keys.insert = 0xD2
_PUBLIC.keyboard.keys.delete = 0xD3
-- Function keys
_PUBLIC.keyboard.keys.f1 = 0x3B
_PUBLIC.keyboard.keys.f2 = 0x3C
_PUBLIC.keyboard.keys.f3 = 0x3D
_PUBLIC.keyboard.keys.f4 = 0x3E
_PUBLIC.keyboard.keys.f5 = 0x3F
_PUBLIC.keyboard.keys.f6 = 0x40
_PUBLIC.keyboard.keys.f7 = 0x41
_PUBLIC.keyboard.keys.f8 = 0x42
_PUBLIC.keyboard.keys.f9 = 0x43
_PUBLIC.keyboard.keys.f10 = 0x44
_PUBLIC.keyboard.keys.f11 = 0x57
_PUBLIC.keyboard.keys.f12 = 0x58
_PUBLIC.keyboard.keys.f13 = 0x64
_PUBLIC.keyboard.keys.f14 = 0x65
_PUBLIC.keyboard.keys.f15 = 0x66
_PUBLIC.keyboard.keys.f16 = 0x67
_PUBLIC.keyboard.keys.f17 = 0x68
_PUBLIC.keyboard.keys.f18 = 0x69
_PUBLIC.keyboard.keys.f19 = 0x71
-- Japanese keyboards
_PUBLIC.keyboard.keys.kana = 0x70
_PUBLIC.keyboard.keys.kanji = 0x94
_PUBLIC.keyboard.keys.convert = 0x79
_PUBLIC.keyboard.keys.noconvert = 0x7B
_PUBLIC.keyboard.keys.yen = 0x7D
_PUBLIC.keyboard.keys.circumflex = 0x90
_PUBLIC.keyboard.keys.ax = 0x96
-- Numpad
_PUBLIC.keyboard.keys.numpad0 = 0x52
_PUBLIC.keyboard.keys.numpad1 = 0x4F
_PUBLIC.keyboard.keys.numpad2 = 0x50
_PUBLIC.keyboard.keys.numpad3 = 0x51
_PUBLIC.keyboard.keys.numpad4 = 0x4B
_PUBLIC.keyboard.keys.numpad5 = 0x4C
_PUBLIC.keyboard.keys.numpad6 = 0x4D
_PUBLIC.keyboard.keys.numpad7 = 0x47
_PUBLIC.keyboard.keys.numpad8 = 0x48
_PUBLIC.keyboard.keys.numpad9 = 0x49
_PUBLIC.keyboard.keys.numpadmul = 0x37
_PUBLIC.keyboard.keys.numpaddiv = 0xB5
_PUBLIC.keyboard.keys.numpadsub = 0x4A
_PUBLIC.keyboard.keys.numpadadd = 0x4E
_PUBLIC.keyboard.keys.numpaddecimal = 0x53
_PUBLIC.keyboard.keys.numpadcomma = 0xB3
_PUBLIC.keyboard.keys.numpadenter = 0x9C
_PUBLIC.keyboard.keys.numpadequals = 0x8D
-- Create inverse mapping for name lookup.
setmetatable(_PUBLIC.keyboard.keys,
{
__index = function(tbl, k)
if type(k) ~= "number" then return end
for name,value in pairs(tbl) do
if value == k then
return name
end
end
end
})
end
function module.exit()
_G._PUBLIC.keyboard = nil
end
return module
-466
View File
@@ -1,466 +0,0 @@
local module = {}
function module.check()
return true -- Usually always loaded, but maybe it would be worth it to check if the computer has a GPU or not? I'm not sure.
end
function module.init()
local serialize = require("serialize")
local unicode = require("unicode")
local event = require("event")
--local ocelot = component.proxy(component.list("ocelot")())
local component = require("component")
local computer = require("computer")
local gpu = component.gpu
_G._PUBLIC.terminal = {}
_PUBLIC.terminal.cursorPosX = 1
_PUBLIC.terminal.cursorPosY = 1
_PUBLIC.terminal.readHistory = {}
local width, height = gpu.getResolution()
local ANSIColorPalette = {
["dark"] = {
[0] = 0x000000,
[1] = 0x800000,
[2] = 0x008000,
[3] = 0x808000,
[4] = 0x000080,
[5] = 0x800080,
[6] = 0x008080,
[7] = 0xC0C0C0
},
["bright"] = {
[0] = 0x808080,
[1] = 0xFF0000,
[2] = 0x00FF00,
[3] = 0xFFFF00,
[4] = 0x0000FF,
[5] = 0xFF00FF,
[6] = 0x00FFFF,
[7] = 0xFFFFFF
}
}
defaultForegroundColor = ANSIColorPalette["bright"][7]
defaultBackgroundColor = ANSIColorPalette["dark"][0]
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
local function scrollDown()
local width, height = gpu.getResolution()
if gpu.copy(1,1,width,height,0,-1) then
local prevForeground = gpu.getForeground()
local prevBackground = gpu.getBackground()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1, height, width, 1, " ")
gpu.setForeground(prevForeground)
gpu.setBackground(prevBackground)
_PUBLIC.terminal.cursorPosY=height
end
end
local function newLine()
_PUBLIC.terminal.cursorPosX=1
_PUBLIC.terminal.cursorPosY = _PUBLIC.terminal.cursorPosY + 1
if _PUBLIC.terminal.cursorPosY>height then
scrollDown()
end
end
local function parseCodeNumbers(code)
local o = {}
for num in code:sub(3,-2):gmatch("[^;]+") do
table.insert(o,tonumber(num))
end
return o
end
local function from8BitColor(num)
num=math.floor(num)&255
if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end
if num>=232 then return 0x10101*(8+(num-232)*10) end
num=num-16
local palette = {0,95,135,175,215,255}
return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1]
end
local function from24BitColor(r,g,b)
r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255
return (r<<16)|(g<<8)|b
end
local function findCodeEnd(text,i)
local function inRange(v,min,max)
return v>=min and v<=max
end
i=i+2
while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
return i
end
function _PUBLIC.terminal.write(text, textWrap)
local width, height = gpu.getResolution()
-- you don't know how tiring this was just for ANSI escape code support
if textWrap == nil then
textWrap = true
end
if not text or not tostring(text) then
return
end
if text:find("\a") then
computer.beep()
end
text = tostring(text)
text = "\27[0m" .. text:gsub("\t", " ")
local readBreak = 0
-- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character.
-- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done.
local section = ""
local function printSection()
if #section==0 then
return
end
while true do
gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,section)
if unicode.wlen(section) > width - _PUBLIC.terminal.cursorPosX + 1 and textWrap then
section = section:sub(width - _PUBLIC.terminal.cursorPosX + 2)
newLine()
else
_PUBLIC.terminal.cursorPosX = _PUBLIC.terminal.cursorPosX+unicode.wlen(section)
break
end
end
section = ""
end
for i=1,#text do
if readBreak>0 then
readBreak = readBreak - 1
goto continue
end
if string.byte(text,i)==10 then
printSection()
newLine()
elseif string.byte(text,i)==13 then
printSection()
_PUBLIC.terminal.cursorPosX=1
elseif string.byte(text,i)==0x1b and i<=#text-2 then
printSection()
--ocelot.log("0x1b char detected")
local codeType = string.sub(text,i+1,i+1)
if codeType=="[" then
-- Control Sequence Introducer
--ocelot.log("Control Sequence Introducer")
local codeEndIdx = findCodeEnd(text,i)
-- codeEndIdx = string.find(text,"m",i)
local code = string.sub(text,i,codeEndIdx)
--ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")")
readBreak = readBreak + #code - 1
local nums = parseCodeNumbers(code)
local codeEnd = code:sub(-1)
--ocelot.log("Code end: "..codeEnd..", "..#codeEnd)
if codeEnd == "m" then
-- Select Graphic Rendition
--ocelot.log("Select Graphic Rendition, ID "..nums[1])
if nums[1]>=30 and nums[1]<=37 then
gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==38 and nums[2]==5 then
gpu.setForeground(from8BitColor(nums[3]))
end
if nums[1]==38 and nums[2]==2 then
gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==39 or nums[1]==0 then
gpu.setForeground(defaultForegroundColor)
end
if nums[1]>=40 and nums[1]<=47 then
gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==48 and nums[2]==5 then
gpu.setBackground(from8BitColor(nums[3]))
end
if nums[1]==48 and nums[2]==2 then
gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==49 or nums[1]==0 then
gpu.setBackground(defaultBackgroundColor)
end
if nums[1]>=90 and nums[1]<=97 then
gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10])
end
if nums[1]>=100 and nums[1]<=107 then
gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10])
end
end
end
else
--gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,string.sub(text,i,i))
section = section..string.sub(text,i,i)
end
::continue::
end
printSection()
end
function _G.print(...)
local args = {...}
local stringArgs = {}
for _, arg in pairs(args) do
if type(arg)=="table" then
table.insert(stringArgs, serialize.table(arg,true))
elseif tostring(arg) then
table.insert(stringArgs, tostring(arg))
end
end
_PUBLIC.terminal.write(table.concat(stringArgs, " ") .. "\n")
end
function _G._PUBLIC.terminal.clear()
width, height = gpu.getResolution()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1,1,width,height," ")
_PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY = 1, 1
end
function _G._PUBLIC.terminal.read(readHistoryType, prefix, defaultText, maxChars)
checkArg(1, readHistoryType, "string", "nil")
checkArg(2, prefix, "string", "nil")
checkArg(3, defaultText, "string", "nil")
checkArg(4, maxChars, "number", "nil")
maxChars = maxChars or math.huge
local text = defaultText or ""
local historyIdx
if readHistoryType then
if not _PUBLIC.terminal.readHistory[readHistoryType] then
_PUBLIC.terminal.readHistory[readHistoryType] = {text}
elseif _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType] ] ~= "" then
table.insert(_PUBLIC.terminal.readHistory[readHistoryType], text)
end
historyIdx = #_PUBLIC.terminal.readHistory[readHistoryType]
end
local function updateHistory()
if not readHistoryType then return end
_PUBLIC.terminal.readHistory[readHistoryType][historyIdx]=text
end
local cur = unicode.len(text)+1
if prefix then _PUBLIC.terminal.write(prefix) end
local startX, startY = _PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY
local fg, bg = gpu.getForeground(), gpu.getBackground()
local cursorBlink = true
local function get(idx)
idx=startX+idx-1
return gpu.get(idx%width,startY+(idx//width))
end
local function checkScroll(y)
for i=1,y-height do
scrollDown()
startY=startY-1
end
return math.min(y,height)
end
local function set(idx,chr,rev)
if chr==nil or chr=="" then return end
if rev then
gpu.setForeground(bg)
gpu.setBackground(fg)
else
gpu.setForeground(fg)
gpu.setBackground(bg)
end
idx=startX+idx-1
local setX, setY = (idx-1)%width+1, startY+((idx-1)//width+1)-1
setY = checkScroll(setY)
gpu.set(setX,setY,unicode.sub(chr,1,width-setX+1))
for i=1,math.ceil((#chr+setX-1)/width)+1 do
gpu.set(1,setY+i,unicode.sub(chr,2-setX+i*width,width+i*width-setX))
setY = checkScroll(setY)
end
end
local function strDef(a,b)
if #a==0 then return b end
return a
end
local function curPos(cur)
return unicode.wlen(unicode.sub(text,1,cur-1))+1
end
local function add(chr)
if type(chr)~="string" or #chr==0 then return end
if unicode.len(text)>=maxChars then return end
if maxChars<math.huge then
chr=unicode.sub(chr,1,maxChars-unicode.len(text))
end
text=unicode.sub(text,1,cur-1)..chr..unicode.sub(text,cur)
set(curPos(cur),chr,false)
cur=math.min(cur+unicode.len(chr),maxChars+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur+1),unicode.sub(text,cur+1),false)
end
local function moveCur(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=math.max(math.min(cur+dir,unicode.len(text)+1),1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function isLetter(chr)
return not string.find("\x09 :@-./_~?&=%+#",chr,1,true)
end
local function nextCur(dir,chr,icur)
if icur==nil then icur=cur end
local next = math.max(math.min(icur+dir,unicode.len(text)+1),1)
if chr then return unicode.sub(text,next,next) end
return next
end
local function curAfterWord(dir)
local ncur = cur
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==1) do
ncur=nextCur(dir,false,ncur)
end
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==-1) do
ncur=nextCur(dir,false,ncur)
end
return ncur
end
local function moveWord(dir)
if nextCur(dir)==cur then return end
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=curAfterWord(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function deleteWord(dir)
local after = curAfterWord(dir)
local lenb = unicode.wlen(text)
if dir==1 then
text=unicode.sub(text,1,cur-1)..unicode.sub(text,after)
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
else
text = unicode.sub(text,1,after-1)..unicode.sub(text,cur)
cur=after
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
end
updateHistory()
cursorBlink = true
end
local function isLine(chr)
return chr=="\n" or chr=="\r"
end
--[[ gpu.set(startX,startY,unicode.sub(text,1,width-startX))
for i=1,(#text+startX)//width-1 do
gpu.set(startX,startY+i,unicode.sub(text,1+i*width,width-startX+i*width))
end ]]
set(1,text,false)
set(curPos(cur)," ",true)
local function reprint(new)
set(1,new..string.rep(" ",unicode.wlen(text)-unicode.wlen(new)+1),false)
cur=unicode.len(new)+1
text=new
set(curPos(cur)," ",true)
end
while true do
local args = {event.pull("key_down", "clipboard", 0.5)}
if args and args[1] == "key_down" and args[4] then
local key = _PUBLIC.keyboard.keys[args[4]]
if key=="up" and readHistoryType then
historyIdx=math.max(historyIdx-1,1)
reprint(_PUBLIC.terminal.readHistory[readHistoryType][historyIdx])
elseif key=="down" and readHistoryType then
historyIdx=math.min(historyIdx+1,#_PUBLIC.terminal.readHistory[readHistoryType])
reprint(_PUBLIC.terminal.readHistory[readHistoryType][historyIdx])
elseif key=="left" and _PUBLIC.keyboard.ctrlDown then
moveWord(-1)
elseif key=="right" and _PUBLIC.keyboard.ctrlDown then
moveWord(1)
elseif key=="left" then
moveCur(-1)
elseif key=="right" then
moveCur(1)
elseif key=="home" then
moveCur(-math.huge)
elseif key=="end" then
moveCur(math.huge)
elseif key=="back" and _PUBLIC.keyboard.ctrlDown then
deleteWord(-1)
elseif key=="delete" and _PUBLIC.keyboard.ctrlDown then
deleteWord(1)
elseif key=="back" and cur>1 then
text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur)
cur=cur-1
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur)+1,unicode.sub(text,cur+1).." ",false)
updateHistory()
elseif key=="delete" then
text = unicode.sub(text,1,cur-1)..unicode.sub(text,cur+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
if cur<=unicode.len(text) then
set(curPos(cur+1),unicode.sub(text,cur+1).." ",false)
end
updateHistory()
elseif key=="enter" then
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
break
elseif not (args[3]<32 or (args[3]>0x7F and args[3]<=0x9F)) then
add(unicode.char(args[3]) or " ")
updateHistory()
end
elseif args and args[1]=="clipboard" then
local clip = args[3]
if not args[3] then goto continue end
while isLine(unicode.sub(clip,1,1)) do clip=unicode.sub(clip,2) end
while isLine(unicode.sub(clip,-1)) do clip=unicode.sub(clip,1,-2) end
add(clip)
updateHistory()
else
cursorBlink=not cursorBlink
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),cursorBlink)
end
::continue::
end
if readHistoryType then
if _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType]]=="" then
table.remove(_PUBLIC.terminal.readHistory[readHistoryType],#_PUBLIC.terminal.readHistory[readHistoryType])
end
if historyIdx<#_PUBLIC.terminal.readHistory[readHistoryType] then
table.remove(_PUBLIC.terminal.readHistory[readHistoryType],historyIdx)
table.insert(_PUBLIC.terminal.readHistory[readHistoryType],text)
end
while #_PUBLIC.terminal.readHistory[readHistoryType] > 50 do
table.remove(_PUBLIC.terminal.readHistory[readHistoryType], 1)
end
end
_PUBLIC.terminal.cursorPosX=1
_PUBLIC.terminal.cursorPosY=_PUBLIC.terminal.cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width)
if _PUBLIC.terminal.cursorPosY>height then scrollDown() end
return text
end
end
function module.exit()
_G._PUBLIC.terminal = nil
end
return module
-149
View File
@@ -1,149 +0,0 @@
_G._PUBLIC.tsched = {}
_G.tsched = {}
_G.tsched.tasks = {}
local currentTask
local component = require("component")
local computer = require("computer")
local filesystem = require("filesystem")
local json = require("json")
local gpu = component.gpu
local ocelot = component.ocelot
function _G._PUBLIC.tsched.runAsTask(path,...)
local args = {...}
local function taskFunction()
local result, errorMessage = xpcall(function(...)
local args = table.pack(...)
if not filesystem.exists(path) then
error("No such file: " .. path)
end
local handle, data, tmpdata = filesystem.open(path), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
-- Userland environment definition
local userland = table.copy(_PUBLIC)
userland._G = userland
assert(load(data, "="..path, "t", userland))(table.unpack(args))
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, path, table.unpack(args))
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
--require(path, table.unpack(args))
end
_PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$"))
end
function _G._PUBLIC.tsched.addTask(func, name)
ocelot.log("Added task " .. name)
local task = coroutine.create(func)
table.insert(tsched.tasks, {["task"] = task, ["name"] = name})
return task
end
function _G._PUBLIC.tsched.removeTask(id)
-- TODO: Check for user permissions before running
table.remove(_G.tsched.tasks, id)
end
function handleError(errormsg)
if errormsg == nil then -- TODO: Replace with proper error handling (if this isn't considered proper..?)
print("\27[91munknown error" .. "\n \n" .. debug.traceback())
else
print("\27[91m" .. tostring(errormsg) .. "\n \n" .. debug.traceback())
end
end
local function runTasks()
for i = 1, #_G.tsched.tasks do
if tsched.tasks[i] then
currentTask = tsched.tasks[i]
local result, errorMessage = coroutine.resume(tsched.tasks[i].task)
if not result then
handleError(errorMessage)
end
if coroutine.status(tsched.tasks[i].task) == "dead" then
_PUBLIC.tsched.removeTask(i)
--ocelot.log("Removed coroutine")
i = i - 1
end
--computer.pullSignal(0)
--coroutine.yield()
end
end
end
function _G._PUBLIC.tsched.getCurrentTask()
return table.copy(currentTask)
end
function _G._PUBLIC.tsched.getTasks()
return table.copy(tsched.tasks)
end
local function taskFunction()
local result, errorMessage = xpcall(function()
if not filesystem.exists("/halyde/kernel/evmgr.lua") then
error("No such file: /halyde/kernel/evmgr.lua")
end
local handle, data, tmpdata = filesystem.open("/halyde/kernel/evmgr.lua"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
assert(load(data, "=/halyde/kernel/evmgr.lua"))()
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, "/halyde/kernel/evmgr.lua")
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
end
_PUBLIC.tsched.addTask(taskFunction, "evmgr")
package.preload("event")
local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
for _, line in ipairs(json.decode(data)) do
if line ~= "" then
--[[ if _G.print then
print(line)
end ]]
_G._PUBLIC.tsched.runAsTask(line)
runTasks()
end
end
-- _G.cormgr.loadCoroutine("/halyde/core/shell.lua")
while true do
runTasks()
if #_G.tsched.tasks == 0 then
computer.beep(1000, 0.5)
while true do
computer.pullSignal()
end
end
end
+1 -1
View File
@@ -1,4 +1,4 @@
local computer = require("computer")
local computer = import("computer")
local event = {}
local bufferTime = 0.1 -- A little bit of buffer time so events won't be skipped by accident.
@@ -1,14 +1,14 @@
local loadfile = ... -- raw loadfile from boot.lua
local unicode, component, computer
local component, computer
if loadfile then
unicode = loadfile("/lib/unicode.lua")(loadfile)
component = loadfile("/lib/component.lua")(loadfile)
unicode = loadfile("/halyde/lib/unicode.lua")(loadfile)
component = loadfile("/halyde/lib/component.lua")(loadfile)
computer = _G.computer
elseif require then
unicode = require("unicode")
component = require("component")
computer = require("computer")
elseif import then
unicode = import("unicode")
component = import("component")
computer = import("computer")
end
local filesystem = {}
+1 -1
View File
@@ -9,7 +9,7 @@ local raster = {
["backgroundColor"]=0xFFFFFF
}
local component = require("component")
local component = import("component")
-- local ocelot = component.proxy(component.list("ocelot")())
local gpu = component.gpu
-4
View File
@@ -1,4 +0,0 @@
[00:00:04:12] Debug!
[00:00:04:19] Info!
[00:00:04:25] Warning!
[00:00:04:32] Error!
-7
View File
@@ -1,7 +0,0 @@
local cor = coroutine.create(function()
print("Hello World!")
end)
print(coroutine.status(cor))
coroutine.resume(cor)
print(coroutine.status(cor))
+19 -38
View File
@@ -1,24 +1,5 @@
local gpu = component.proxy(component.list("gpu")())
local resX, resY = gpu.getResolution()
-- Architecture check
local foundArchitecture = false
for _, arch in pairs(computer.getArchitectures()) do
if arch == "Lua 5.3" then
foundArchitecture = true
break
end
end
if foundArchitecture then
computer.setArchitecture("Lua 5.3")
else
gpu.set(1, 1, "Required architecture (Lua 5.3) is not supported.")
gpu.set(1, 2, "Halting.")
while true do
computer.pullSignal()
end
end
local resx, resy = gpu.getResolution()
local function loadfile(file)
checkArg(1, file, "string")
@@ -36,36 +17,36 @@ local function handleError(errorMessage)
return(errorMessage.."\n \n"..debug.traceback())
end
function loadBoot()
loadfile("/halyde/kernel/boot.lua")(loadfile)
function loadthething()
loadfile("/halyde/core/boot.lua")(loadfile)
end
gpu.setBackground(0x000000)
gpu.fill(1, 1, resX, resY, " ")
-- Copying low-level functions in case of post-preload failure
local pullSignal = computer.pullSignal
local shutdown = computer.shutdown
local result, reason = xpcall(loadBoot, handleError)
gpu.fill(1, 1, resx, resy, " ")
local result, reason = xpcall(loadthething, handleError)
if not result then
if import then
local computer = import("computer")
end
gpu.setBackground(0x000000)
gpu.fill(1, 1, resX, resY, " ")
gpu.fill(1, 1, resx, resy, " ")
gpu.setBackground(0x800000)
gpu.setForeground(0xFFFFFF)
gpu.set(2,2,"A critical error has occurred.")
local i = 4
reason = tostring(reason):gsub("\t", " ")
for line in string.gmatch(reason or "unknown error", "([^\n]*)\n?") do
reason = reason:gsub("\t", " ")
for line in string.gmatch((reason ~= nil and tostring(reason)) or "unknown error", "([^\n]*)\n?") do
gpu.set(2,i,line)
i = i + 1
end
gpu.set(2,i+1, "Press any key to restart.")
local evname
repeat
evname = pullSignal()
until evname == "key_down"
shutdown(true)
if computer~=nil then
gpu.set(2,i+1, "Press any key to restart.")
local evname
repeat
evname = computer.pullSignal()
until evname == "key_down"
computer.shutdown(true)
end
while true do
coroutine.yield()
end
-30
View File
@@ -1,30 +0,0 @@
local fs = require("filesystem")
local computer = require("computer")
local log = {}
function log.add(text, logType)
checkArg(1, text, "string")
checkArg(2, logType, "string", "nil")
if logType ~= "debug" and logType ~= "info" and logType ~= "warning" and logType ~= "error" and logType then
error("Log type must either be debug, info, warning or error.")
end
if not logType then
logType = "debug"
end
local handle = fs.open("/halyde/system.log", "a")
local time = computer.uptime()
local logText = string.format("[%02d:%02d:%02d:%02d] " .. text, math.floor(time / 86400), math.floor(time / 3600 % 24), math.floor(time / 60 % 60), math.floor(time % 60)) .. "\n"
if logType == "debug" then
handle:write("\27[37m" .. logText)
elseif logType == "info" then
handle:write("\27[97m" .. logText)
elseif logType == "warning" then
handle:write("\27[93m" .. logText)
else
handle:write("\27[91m" .. logText)
end
handle:close()
end
return log