From d3d5f21ab18c577b6aa6c2b84379db9a09807d44 Mon Sep 17 00:00:00 2001 From: Ponali Date: Sun, 14 Sep 2025 13:37:41 +0200 Subject: [PATCH] lots and LOTS of stuff i lost track sorry --- .gitignore | 1 + halyde/apps/help.lua | 8 ++- halyde/apps/helpdb/default.txt | 39 ++++++----- halyde/apps/lua.lua | 4 +- halyde/kernel/boot.lua | 45 ++++++------ halyde/kernel/datatools.lua | 1 + halyde/kernel/evmgr.lua | 30 +++++--- halyde/kernel/modload.lua | 29 +++++--- halyde/kernel/modules/defenv.lua | 1 - halyde/kernel/modules/ipc.lua | 59 ++++++++++++++++ halyde/kernel/modules/terminal.lua | 108 +++++++++++++++++------------ halyde/kernel/tsched.lua | 19 +++-- halyde/shell/shell.lua | 38 ++++++++-- lib/serialize.lua | 14 ++-- 14 files changed, 272 insertions(+), 124 deletions(-) diff --git a/.gitignore b/.gitignore index 71bfb3c..b2fbe54 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .stfolder +home/* diff --git a/halyde/apps/help.lua b/halyde/apps/help.lua index 0b27476..c57d11b 100644 --- a/halyde/apps/help.lua +++ b/halyde/apps/help.lua @@ -1,3 +1,4 @@ +local shell = require("shell") local fs = require("filesystem") local args = {...} local command = args[1] @@ -11,8 +12,9 @@ if not command then print(data) return end -if shell.aliases[command] then - command = shell.aliases[command] +local aliases = shell.getAliases() +if aliases[command] then + command = aliases[command] end if fs.exists("/halyde/apps/helpdb/" .. command .. ".txt") then local handle, data, tmpdata = fs.open("/halyde/apps/helpdb/" .. command .. ".txt", "r"), "", nil @@ -21,7 +23,7 @@ if fs.exists("/halyde/apps/helpdb/" .. command .. ".txt") then data = data .. (tmpdata or "") until not tmpdata print(data) - local aliases = table.copy(shell.aliases) + -- local aliases = table.copy(shell.aliases) if table.find(aliases, command) then local aliasIndex = table.find(aliases, command) local aliasString = "Aliases:\n " .. aliasIndex diff --git a/halyde/apps/helpdb/default.txt b/halyde/apps/helpdb/default.txt index 875935e..3c30d3c 100644 --- a/halyde/apps/helpdb/default.txt +++ b/halyde/apps/helpdb/default.txt @@ -1,22 +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. + 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] diff --git a/halyde/apps/lua.lua b/halyde/apps/lua.lua index 9fc9d64..0e6ec89 100644 --- a/halyde/apps/lua.lua +++ b/halyde/apps/lua.lua @@ -1,6 +1,6 @@ print("\27[44m".._VERSION.."\27[0m shell") print('Type "exit" to exit.') -terminal.readHistory["lua"] = {""} +-- terminal.readHistory["lua"] = {""} local fs = require("filesystem") local loadedLibraries = "" @@ -15,7 +15,7 @@ while true do local command = terminal.read("lua", "\27[44mlua>\27[0m ") if command == "exit" then return - else + elseif command~="" then local function runCommand() local func = load(loadedLibraries.."return "..command,"=stdin") or load(loadedLibraries..command,"=stdin") local res = {assert(func)()} diff --git a/halyde/kernel/boot.lua b/halyde/kernel/boot.lua index cf36067..e9aac73 100644 --- a/halyde/kernel/boot.lua +++ b/halyde/kernel/boot.lua @@ -3,6 +3,7 @@ local filesystem = assert(loadfile("/lib/filesystem.lua")(loadfile)) _G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file _G._OSLOGO = "" _G._PUBLIC = {} +_G._PUBLIC.unicode = assert(loadfile("/lib/unicode.lua")(loadfile)) local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil repeat @@ -14,29 +15,33 @@ _G.package = {["preloaded"] = {}} loadfile("/halyde/kernel/modules/datatools.lua")() -function _G.require(module, ...) - local args = table.pack(...) - if package.preloaded[module] then - return package.preloaded[module] +function _G.reqgen(load) + return function(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 - 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 +_G.require = reqgen(_G.load) + function _G.package.preload(module) local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil repeat diff --git a/halyde/kernel/datatools.lua b/halyde/kernel/datatools.lua index b7b80e5..0f57d9e 100644 --- a/halyde/kernel/datatools.lua +++ b/halyde/kernel/datatools.lua @@ -13,6 +13,7 @@ local conversionTables = { } function table.find(tab, item) + checkArg(1,tab,"table") for k, v in pairs(tab) do if v == item then return k diff --git a/halyde/kernel/evmgr.lua b/halyde/kernel/evmgr.lua index b5525d3..e9bf8f4 100644 --- a/halyde/kernel/evmgr.lua +++ b/halyde/kernel/evmgr.lua @@ -4,9 +4,19 @@ local maxEventQueueLength = 10 -- increase if events start getting dropped local computer = require("computer") -_G._PUBLIC.keyboard.ctrlDown = false -_G._PUBLIC.keyboard.altDown = false -_G._PUBLIC.keyboard.shiftDown = false +local ctrlDown = false +local altDown = false +local shiftDown = false + +function _G._PUBLIC.keyboard.getCtrlDown() + return ctrlDown +end +function _G._PUBLIC.keyboard.getAltDown() + return altDown +end +function _G._PUBLIC.keyboard.getShiftDown() + return shiftDown +end --local ocelot = component.proxy(component.list("ocelot")()) @@ -21,12 +31,12 @@ while true do local keycode = args[5] local key = _PUBLIC.keyboard.keys[keycode] if key == "lcontrol" then - _PUBLIC.keyboard.ctrlDown = true + ctrlDown = true elseif key == "lmenu" then - _PUBLIC.keyboard.altDown = true + altDown = true elseif key == "lshift" then - _PUBLIC.keyboard.shiftDown = true - elseif key == "c" and _PUBLIC.keyboard.ctrlDown and _PUBLIC.keyboard.altDown then + shiftDown = true + elseif key == "c" and ctrlDown and altDown then if print then print("\n\27[91mCoroutine "..tostring(#tsched.tasks).." killed.") end @@ -36,11 +46,11 @@ while true do local keycode = args[5] local key = _PUBLIC.keyboard.keys[keycode] if key == "lcontrol" then - _PUBLIC.keyboard.ctrlDown = false + ctrlDown = false elseif key == "lmenu" then - _PUBLIC.keyboard.altDown = false + altDown = false elseif key == "lshift" then - _PUBLIC.keyboard.shiftDown = true + shiftDown = true end end end diff --git a/halyde/kernel/modload.lua b/halyde/kernel/modload.lua index 9cab079..68c863a 100644 --- a/halyde/kernel/modload.lua +++ b/halyde/kernel/modload.lua @@ -1,21 +1,24 @@ +local log = require("log") local fs = require("filesystem") local modulePath = "/halyde/kernel/modules" -local modules = assert(fs.list(modulePath)) +local moduleList = assert(fs.list(modulePath)) +local modules = {} local moduleTypes = {} local function loadModule(modName) - local moduleData = assert(require(fs.concat(modulePath, modName)), "Module did not return anything!") -- TODO: Make this not actually throw an error, rather put something in the log and move on - table.remove(modules, table.find(modules, modName)) + local moduleData = modules[modName] + table.remove(moduleList, table.find(moduleList, modName)) + if not moduleData then return end if not moduleData.check() then return end if moduleData.dependencies then for _, dependency in pairs(moduleData.dependencies) do - if table.find(modules, dependency) then + if table.find(moduleList, dependency) then loadModule(dependency) - elseif table.find(modules, dependency .. ".lua") then + elseif table.find(moduleList, dependency .. ".lua") then loadModule(dependency .. ".lua") else for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do @@ -33,16 +36,22 @@ local function loadModule(modName) end end -for _, modName in pairs(modules) do -- Get all the module types - local moduleData = assert(require(fs.concat(modulePath, modName)), "Module did not return anything!") -- TODO: Make this not actually throw an error, rather put something in the log and move on +for _, modName in pairs(moduleList) do -- Get all the module types + local moduleData = require(fs.concat(modulePath, modName)) -- TODO: Make this not actually throw an error, rather put something in the log and move on + if type(moduleData)~="table" then + log.add(string.format("[modload: %s] Module returned invalid type (%s) - skipping",modName,type(moduleData)),"error") + goto continue + end + modules[modName]=moduleData 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 + ::continue:: 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]) +while moduleList[1] do + if moduleList[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config + loadModule(moduleList[1]) end end diff --git a/halyde/kernel/modules/defenv.lua b/halyde/kernel/modules/defenv.lua index a3ab3a5..430584c 100644 --- a/halyde/kernel/modules/defenv.lua +++ b/halyde/kernel/modules/defenv.lua @@ -9,7 +9,6 @@ end function module.init() local publicTable = { "print", - "require", "_VERSION", "_OSVERSION", "assert", diff --git a/halyde/kernel/modules/ipc.lua b/halyde/kernel/modules/ipc.lua index 13e7e7e..1698702 100644 --- a/halyde/kernel/modules/ipc.lua +++ b/halyde/kernel/modules/ipc.lua @@ -48,6 +48,24 @@ function module.init() return nil end return globalTable.vars[key] + end,["__pairs"]=function() + if not _G.ipc.shared[currentPID] then + return pairs({}) + end + local globalTable + for _, tab in pairs(_G.ipc.shared[currentPID]) do + if tab.sharedWith == pid then + globalTable = tab + end + end + if not globalTable then + return pairs({}) + end + if not globalTable.vars then + return pairs({}) + end + + return pairs(table.copy(globalTable.vars)) end}) return shareTable end @@ -75,6 +93,8 @@ function module.init() end globalTable.vars[key] = value end, ["__index"] = function(_, key) + print(_G.ipc.shared) + local currentPID = _PUBLIC.tsched.getCurrentTask().id if not _G.ipc.shared[currentPID] then return nil @@ -92,7 +112,40 @@ function module.init() return nil end return globalTable.vars[key] + end,["__pairs"]=function() + if not _G.ipc.shared[currentPID] then + return pairs({}) + end + local globalTable + for _, tab in pairs(_G.ipc.shared[currentPID]) do + if tab.sharedWith == pid then + globalTable = tab + end + end + if not globalTable then + return pairs({}) + end + if not globalTable.vars then + return pairs({}) + end + + return pairs(table.copy(globalTable.vars)) end}) + + -- check if the reverse is also available + --[[ if not _G.ipc.shared[pid] then + _G.ipc.shared[pid]={} + end + for _, tab in pairs(_G.ipc.shared[pid]) do + if tab.sharedWith == currentPID then + return -- it's already added + end + end + local reverseTable = {} + reverseTable.vars = globalTable.vars + reverseTable.sharedWith = currentPID + table.insert(_G.ipc.shared[pid],reverseTable) ]] + return shareTable end @@ -114,6 +167,12 @@ function module.init() end end return returnTable + end,["__pairs"]=function() + local ftbl = {} + for i in pairs(_G.ipc.shared) do + ftbl[i]=_PUBLIC.ipc.shared[i] + end + return pairs(ftbl) end}) end diff --git a/halyde/kernel/modules/terminal.lua b/halyde/kernel/modules/terminal.lua index 2d8fc94..ffd254f 100644 --- a/halyde/kernel/modules/terminal.lua +++ b/halyde/kernel/modules/terminal.lua @@ -14,11 +14,36 @@ function module.init() local computer = require("computer") local gpu = component.gpu _G._PUBLIC.terminal = {} - _PUBLIC.terminal.cursorPosX = 1 - _PUBLIC.terminal.cursorPosY = 1 - _PUBLIC.terminal.readHistory = {} - + local cursorPosX = 1 + local cursorPosY = 1 local width, height = gpu.getResolution() + function _PUBLIC.terminal.getCursorPos() + return cursorPosX,cursorPosY + end + function _PUBLIC.terminal.setCursorPos(x,y) + checkArg(1,x,"number","nil") + checkArg(2,y,"number","nil") + if type(x)~=nil then cursorPosX=math.min(math.max(x,1),width) end + if type(y)~=nil then cursorPosY=math.min(math.max(y,1),height) end + end + local readHistory = {} + function _PUBLIC.terminal.getHistory(id) + checkArg(1,id,"string") + return table.copy(readHistory[id]) + end + function _PUBLIC.terminal.setHistory(id,hist) + checkArg(1,id,"string") + checkArg(2,hist,"table") + for i=1,#hist do + hist[i]=tostring(hist[i]) + end + readHistory[id]=hist + end + function _PUBLIC.terminal.addToHistory(id,hist) + checkArg(1,id,"string") + checkArg(2,hist,"string") + table.insert(readHistory[id],hist) + end local ANSIColorPalette = { ["dark"] = { @@ -50,7 +75,6 @@ function module.init() 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() @@ -59,14 +83,14 @@ function module.init() gpu.fill(1, height, width, 1, " ") gpu.setForeground(prevForeground) gpu.setBackground(prevBackground) - _PUBLIC.terminal.cursorPosY=height + cursorPosY=height end end local function newLine() - _PUBLIC.terminal.cursorPosX=1 - _PUBLIC.terminal.cursorPosY = _PUBLIC.terminal.cursorPosY + 1 - if _PUBLIC.terminal.cursorPosY>height then + cursorPosX=1 + cursorPosY = cursorPosY + 1 + if cursorPosY>height then scrollDown() end end @@ -103,8 +127,6 @@ function module.init() 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 @@ -129,12 +151,12 @@ function module.init() 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) + gpu.set(cursorPosX,cursorPosY,section) + if unicode.wlen(section) > width - cursorPosX + 1 and textWrap then + section = section:sub(width - cursorPosX + 2) newLine() else - _PUBLIC.terminal.cursorPosX = _PUBLIC.terminal.cursorPosX+unicode.wlen(section) + cursorPosX = cursorPosX+unicode.wlen(section) break end end @@ -152,7 +174,7 @@ function module.init() newLine() elseif string.byte(text,i)==13 then printSection() - _PUBLIC.terminal.cursorPosX=1 + cursorPosX=1 elseif string.byte(text,i)==0x1b and i<=#text-2 then printSection() --ocelot.log("0x1b char detected") @@ -204,7 +226,7 @@ function module.init() end end else - --gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,string.sub(text,i,i)) + --gpu.set(cursorPosX,cursorPosY,string.sub(text,i,i)) section = section..string.sub(text,i,i) end ::continue:: @@ -226,11 +248,10 @@ function module.init() 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 + cursorPosX, cursorPosY = 1, 1 end function _G._PUBLIC.terminal.read(readHistoryType, prefix, defaultText, maxChars) @@ -244,22 +265,22 @@ function module.init() 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) + if not readHistory[readHistoryType] then + readHistory[readHistoryType] = {text} + elseif readHistory[readHistoryType][#readHistory[readHistoryType] ] ~= text then + table.insert(readHistory[readHistoryType], text) end - historyIdx = #_PUBLIC.terminal.readHistory[readHistoryType] + historyIdx = #readHistory[readHistoryType] end local function updateHistory() if not readHistoryType then return end - _PUBLIC.terminal.readHistory[readHistoryType][historyIdx]=text + 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 startX, startY = cursorPosX, cursorPosY local fg, bg = gpu.getForeground(), gpu.getBackground() local cursorBlink = true local function get(idx) @@ -378,17 +399,18 @@ function module.init() while true do local args = {event.pull("key_down", "clipboard", 0.5)} + local ctrlDown = _PUBLIC.keyboard.getCtrlDown() 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]) + reprint(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 + historyIdx=math.min(historyIdx+1,#readHistory[readHistoryType]) + reprint(readHistory[readHistoryType][historyIdx]) + elseif key=="left" and ctrlDown then moveWord(-1) - elseif key=="right" and _PUBLIC.keyboard.ctrlDown then + elseif key=="right" and ctrlDown then moveWord(1) elseif key=="left" then moveCur(-1) @@ -398,9 +420,9 @@ function module.init() moveCur(-math.huge) elseif key=="end" then moveCur(math.huge) - elseif key=="back" and _PUBLIC.keyboard.ctrlDown then + elseif key=="back" and ctrlDown then deleteWord(-1) - elseif key=="delete" and _PUBLIC.keyboard.ctrlDown then + elseif key=="delete" and ctrlDown then deleteWord(1) elseif key=="back" and cur>1 then text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur) @@ -439,21 +461,21 @@ function module.init() end if readHistoryType then - if _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType]]=="" then - table.remove(_PUBLIC.terminal.readHistory[readHistoryType],#_PUBLIC.terminal.readHistory[readHistoryType]) + if readHistory[readHistoryType][#readHistory[readHistoryType]]=="" then + table.remove(readHistory[readHistoryType],#readHistory[readHistoryType]) end - if historyIdx<#_PUBLIC.terminal.readHistory[readHistoryType] then - table.remove(_PUBLIC.terminal.readHistory[readHistoryType],historyIdx) - table.insert(_PUBLIC.terminal.readHistory[readHistoryType],text) + if historyIdx<#readHistory[readHistoryType] then + table.remove(readHistory[readHistoryType],historyIdx) + table.insert(readHistory[readHistoryType],text) end - while #_PUBLIC.terminal.readHistory[readHistoryType] > 50 do - table.remove(_PUBLIC.terminal.readHistory[readHistoryType], 1) + while #readHistory[readHistoryType] > 50 do + table.remove(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 + cursorPosX=1 + cursorPosY=cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width) + if cursorPosY>height then scrollDown() end return text end diff --git a/halyde/kernel/tsched.lua b/halyde/kernel/tsched.lua index 1a341b4..4b35129 100644 --- a/halyde/kernel/tsched.lua +++ b/halyde/kernel/tsched.lua @@ -29,11 +29,16 @@ function _G._PUBLIC.tsched.runAsTask(path,...) -- Userland environment definition local userland = table.copy(_PUBLIC) userland._G = userland + userland.load=function(chunk,chunkname,mode,env) + if not env or env==_G then env=userland end -- if they SOMEHOW get the kernel environment they're not running jack shit + return load(chunk,chunkname,mode,env) + end + userland.require = reqgen(userland.load) assert(load(data, "="..path, "t", userland))(table.unpack(args)) end, function(errorMessage) return errorMessage .. "\n \n" .. debug.traceback() - end, path, table.unpack(args)) + end, --[[ path,]] table.unpack(args)) if not result then if print then gpu.freeAllBuffers() @@ -44,14 +49,20 @@ function _G._PUBLIC.tsched.runAsTask(path,...) end --require(path, table.unpack(args)) end - _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) + local _,taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) + taskInfo.path = path + taskInfo.args = table.copy(args) end function _G._PUBLIC.tsched.addTask(func, name) local task = coroutine.create(func) - table.insert(tsched.tasks, {["task"] = task, ["name"] = name, ["id"] = idCounter}) + local taskInfo = {["task"] = task, ["name"] = name, ["id"] = idCounter} + if currentTask and type(currentTask.id)=="number" then + taskInfo.parent = currentTask.id + end + table.insert(tsched.tasks, taskInfo) idCounter = idCounter + 1 - return task + return task, taskInfo end function _G._PUBLIC.tsched.removeTask(id) diff --git a/halyde/shell/shell.lua b/halyde/shell/shell.lua index 38cb3f9..65afe1d 100644 --- a/halyde/shell/shell.lua +++ b/halyde/shell/shell.lua @@ -10,9 +10,30 @@ local shellcfg = json.decode(data) local component = require("component") local gpu = component.gpu +local workingDirectory = shellcfg["defaultWorkingDirectory"] +local aliases = shellcfg["aliases"] + _G.shell = {} -_G.shell.workingDirectory = shellcfg["defaultWorkingDirectory"] -_G.shell.aliases = shellcfg["aliases"] + +function _G.shell.getWorkingDirectory() + return workingDirectory +end +function _G.shell.setWorkingDirectory(dir) + checkArg(1, dir, "string") + workingDirectory = dir +end +function _G.shell.getAliases() + return table.copy(aliases) +end +function _G.shell.addAlias(executable, aliasName) + checkArg(1, executable, "string") + checkArg(2, aliasName, "string") + aliases[aliasName]=executable +end +function _G.shell.removeAlias(aliasName) + checkArg(1, aliasName, "string") + aliases[aliasName]=nil +end local function runAsTask(path, ...) --ocelot.log("running " .. path .. " as coroutine") @@ -36,9 +57,9 @@ end function _G.shell.run(command) checkArg(1, command, "string") - if shell.aliases[command:match("[^ ]+")] then + if aliases[command:match("[^ ]+")] then local _, cmdend = command:find("[^ ]+") - command = shell.aliases[command:match("[^ ]+")] .. command:sub(cmdend + 1) + command = aliases[command:match("[^ ]+")] .. command:sub(cmdend + 1) end local gm, result, args, trimmedCommand = command:gmatch("[^ ]+"), nil, {}, command while true do @@ -98,6 +119,9 @@ function _G.shell.run(command) print("No such file or command: "..args[1]) end +local shareTable = ipc.shareWithAll() +shareTable.shell = _G.shell + print(shellcfg["startupMessage"]:format(_OSVERSION, shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)])) while true do coroutine.yield() @@ -105,10 +129,10 @@ while true do --print(shellcfg["prompt"]:format(shell.workingDirectory),false) -- termlib.cursorPosX = #(shell.workingDirectory .. " > ") -- termlib.cursorPosY = termlib.cursorPosY - 1 - if shell.workingDirectory:sub(-1, -1) ~= "/" then - shell.workingDirectory = shell.workingDirectory .. "/" + if workingDirectory:sub(-1, -1) ~= "/" then + workingDirectory = workingDirectory .. "/" end - local shellCommand = terminal.read("shell", shellcfg.prompt:format(shell.workingDirectory)) + local shellCommand = terminal.read("shell", shellcfg.prompt:format(workingDirectory)) shell.run(shellCommand) gpu.freeAllBuffers() end diff --git a/lib/serialize.lua b/lib/serialize.lua index eaefccf..bc6bc44 100644 --- a/lib/serialize.lua +++ b/lib/serialize.lua @@ -83,6 +83,7 @@ function serialize.table(tbl,colors,stack) local metatbl = getmetatable(tbl) local metakeys = {} + local metastring = "" if type(metatbl)=="table" then for i,v in pairs(metatbl) do keyNumber=false @@ -91,16 +92,17 @@ function serialize.table(tbl,colors,stack) end if #metakeys>0 then out=out.."\n " - if colors then out=out.."\x1b[92m" end + if colors then metastring=metastring.."\x1b[92m" end if table.find(metakeys,"__tostring") then - out=out.."tostring: "..serialize.string(tostring(tbl)).."\n " + metastring=metastring.."tostring: "..serialize.string(tostring(tbl)).."\n " table.remove(metakeys,table.find(metakeys,"__tostring")) end - out=out..table.concat(metakeys,", ") - if colors then out=out.."\x1b[39m" end + metastring=metastring..table.concat(metakeys,", ") + if colors then metastring=metastring.."\x1b[39m" end + out=out..metastring end - if keyAmount==0 then return "{}" end + if keyAmount==0 then return "{"..metastring.."}" end if keyNumber then -- fix strings not being serialised local vals = {} @@ -117,7 +119,7 @@ function serialize.table(tbl,colors,stack) table.insert(vals,tostring(v)) end end - return "{"..table.concat(vals,", ").."}" + return "{"..table.concat(vals,", ")..(#metakeys>0 and "\n "..metastring or "").."}" end return "{\n"..out.."\n}" end