v1.8.0 - Fixed a bug with shell not executing files in the working directory, added json library, changed all configs to json, added config auto-generation so they don't reset after an update.

This commit is contained in:
TheWahlolly
2025-05-31 09:55:23 +03:00
parent 34f716beaa
commit 41d55113e5
13 changed files with 92 additions and 115 deletions
+5 -4
View File
@@ -1,12 +1,12 @@
local agcfg = { local agcfg = {
["halyde"] = { ["halyde"] = {
["maindir"] = "", ["maindir"] = "",
["version"] = "1.7.2", ["version"] = "1.8.0",
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.", ["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
["directories"] = { ["directories"] = {
"halyde/apps", "halyde/apps",
"halyde/apps/helpdb", "halyde/apps/helpdb",
"halyde/config", "halyde/config/generate",
"halyde/core", "halyde/core",
"halyde/lib", "halyde/lib",
"home" "home"
@@ -38,8 +38,8 @@ local agcfg = {
"halyde/apps/mv.lua", "halyde/apps/mv.lua",
"halyde/apps/rm.lua", "halyde/apps/rm.lua",
"halyde/config/oslogo.ans", "halyde/config/oslogo.ans",
"halyde/config/shell.cfg", "halyde/config/generate/shell.cfg",
"halyde/config/startupapps.cfg", "halyde/config/generate/startupapps.cfg",
"halyde/core/boot.lua", "halyde/core/boot.lua",
"halyde/core/cormgr.lua", "halyde/core/cormgr.lua",
"halyde/core/datatools.lua", "halyde/core/datatools.lua",
@@ -51,6 +51,7 @@ local agcfg = {
"halyde/lib/computer.lua", "halyde/lib/computer.lua",
"halyde/lib/event.lua", "halyde/lib/event.lua",
"halyde/lib/filesystem.lua", "halyde/lib/filesystem.lua",
"halyde/lib/json.lua",
"halyde/lib/raster.lua" "halyde/lib/raster.lua"
} }
}, },
+5 -4
View File
@@ -1,10 +1,10 @@
Ahome/ Ahome/
Ahalyde/lib/ Ahalyde/lib/
Ahalyde/core/ Ahalyde/core/
Ahalyde/config/ Ahalyde/config/generate/
Ahalyde/apps/helpdb/ Ahalyde/apps/helpdb/
Ahalyde/apps/ Ahalyde/apps/
V1.7.2 V1.8.0
Ainit.lua Ainit.lua
Ahalyde/apps/helpdb/cat.txt Ahalyde/apps/helpdb/cat.txt
Ahalyde/apps/helpdb/cd.txt Ahalyde/apps/helpdb/cd.txt
@@ -31,8 +31,8 @@ Ahalyde/apps/mkdir.lua
Ahalyde/apps/mv.lua Ahalyde/apps/mv.lua
Ahalyde/apps/rm.lua Ahalyde/apps/rm.lua
Ahalyde/config/oslogo.ans Ahalyde/config/oslogo.ans
Ahalyde/config/shell.cfg Ahalyde/config/generate/shell.cfg
Ahalyde/config/startupapps.cfg Ahalyde/config/generate/startupapps.cfg
Ahalyde/core/boot.lua Ahalyde/core/boot.lua
Ahalyde/core/cormgr.lua Ahalyde/core/cormgr.lua
Ahalyde/core/datatools.lua Ahalyde/core/datatools.lua
@@ -44,4 +44,5 @@ Ahalyde/lib/component.lua
Ahalyde/lib/computer.lua Ahalyde/lib/computer.lua
Ahalyde/lib/event.lua Ahalyde/lib/event.lua
Ahalyde/lib/filesystem.lua Ahalyde/lib/filesystem.lua
Ahalyde/lib/json.lua
Ahalyde/lib/raster.lua Ahalyde/lib/raster.lua
+1
View File
@@ -0,0 +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"},"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 │ Halyde 1.8.0\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1
View File
@@ -0,0 +1 @@
["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/shell.lua"]
-41
View File
@@ -1,41 +0,0 @@
local shellcfg = {
["startupMessage"] = "\n │\n │ ".._OSVERSION..'\n │ %s\n │\n ', -- message shown on startup. %s will be replaced with splash message.
["prompt"] = "\x1b[92m%s > \x1b[0m", -- shell prompt. %s will be replaced with working directory.
["path"] = { -- default locations where programs will be run from
"/halyde/apps/"
}, ["aliases"] = { -- shell command aliases
["copy"] = "cp",
["move"] = "mv",
["rename"] = "mv",
["ren"] = "mv",
["dir"] = "ls",
["list"] = "ls",
["man"] = "help",
["del"] = "rm",
["delete"] = "rm",
["remove"] = "rm",
[".."] = "cd ..",
["wget"] = "download",
["ag"] = "argentum"
}, ["defaultWorkingDirectory"] = "/home/", -- the working directory that gets set when halyde starts
["splashMessages"] = { -- messages shown on startup
"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!"
}
}
return shellcfg
-3
View File
@@ -1,3 +0,0 @@
/halyde/core/fullkb.lua
/halyde/core/evmgr.lua
/halyde/core/shell.lua
+10 -1
View File
@@ -1,7 +1,7 @@
local loadfile = ... local loadfile = ...
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile) local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
_G._OSVERSION = "Halyde 1.7.2" _G._OSVERSION = "Halyde 1.8.0"
_G._OSLOGO = "" _G._OSLOGO = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat repeat
@@ -85,4 +85,13 @@ preload("computer")
--assert(handle:write("Bazinga!")) --assert(handle:write("Bazinga!"))
--handle:close() --handle:close()
local fs = import("filesystem")
if not fs.exists("/halyde/config/shell.json") then
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") import("/halyde/core/cormgr.lua")
+4 -4
View File
@@ -5,6 +5,7 @@ _G.cormgr.corList = {}
local component = import("component") local component = import("component")
local filesystem = import("filesystem") local filesystem = import("filesystem")
local json = import("json")
local gpu = component.proxy(component.list("gpu")()) local gpu = component.proxy(component.list("gpu")())
function _G.cormgr.loadCoroutine(path, ...) function _G.cormgr.loadCoroutine(path, ...)
@@ -55,14 +56,13 @@ local function runCoroutines()
end end
end end
local handle = filesystem.open("/halyde/config/startupapps.cfg", "r") local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil
local data = ""
local tmpdata
repeat repeat
tmpdata = handle:read(math.huge or math.maxinteger) tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "") data = data .. (tmpdata or "")
until not tmpdata until not tmpdata
for line in data:gmatch("([^\n]*)\n?") do handle:close()
for _, line in ipairs(json.decode(data)) do
if line ~= "" then if line ~= "" then
--[[ if _G.print then --[[ if _G.print then
print(line) print(line)
+6 -7
View File
@@ -12,13 +12,12 @@ keyboard.altDown = false
while true do while true do
local args local args
repeat repeat
args = {computer.pullSignal(0)} args = {computer.uptime(), computer.pullSignal(0)}
if args and args[1] then if args and args[2] then
--ocelot.log("Sending signal "..args..","..computer.uptime())
table.insert(evmgr.eventQueue, args) table.insert(evmgr.eventQueue, args)
if keyboard then if keyboard then
if args[1] == "key_down" then if args[2] == "key_down" then
local keycode = args[4] local keycode = args[5]
local key = keyboard.keys[keycode] local key = keyboard.keys[keycode]
if key == "lcontrol" then if key == "lcontrol" then
keyboard.ctrlDown = true keyboard.ctrlDown = true
@@ -30,8 +29,8 @@ while true do
end end
cormgr.corList[#cormgr.corList] = nil cormgr.corList[#cormgr.corList] = nil
end end
elseif args[1] == "key_up" then elseif args[2] == "key_up" then
local keycode = args[4] local keycode = args[5]
local key = keyboard.keys[keycode] local key = keyboard.keys[keycode]
if key == "lcontrol" then if key == "lcontrol" then
keyboard.ctrlDown = false keyboard.ctrlDown = false
+22 -18
View File
@@ -1,7 +1,14 @@
local shellcfg = import("/halyde/config/shell.cfg") 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)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local shellcfg = json.decode(data)
import("/halyde/core/termlib.lua") import("/halyde/core/termlib.lua")
local event = import("event") local event = import("event")
local filesystem = import("filesystem")
local component = import("component") local component = import("component")
local gpu = component.proxy(component.list("gpu")()) local gpu = component.proxy(component.list("gpu")())
@@ -51,39 +58,36 @@ function _G.shell.run(command)
end end
end end
-- execute the program -- execute the program
local foundfile = false local PATH = table.copy(shellcfg.path)
table.insert(PATH, shell.workingDirectory)
if not args[1] then if not args[1] then
return return
end end
if filesystem.exists(args[1]) and not filesystem.isDirectory(args[1]) then if fs.exists(args[1]) and not fs.isDirectory(args[1]) then
foundfile = true
local path = args[1] local path = args[1]
table.remove(args, 1) table.remove(args, 1)
runAsCoroutine(path, table.unpack(args)) runAsCoroutine(path, table.unpack(args))
else return
for _, item in pairs(shellcfg["path"]) do end
if filesystem.exists(item..args[1]) and not filesystem.isDirectory(item .. args[1]) then for _, item in pairs(PATH) do
foundfile = true if fs.exists(item..args[1]) and not fs.isDirectory(item .. args[1]) then
local path = item..args[1] local path = fs.concat(item, args[1])
table.remove(args, 1) table.remove(args, 1)
runAsCoroutine(path, table.unpack(args)) runAsCoroutine(path, table.unpack(args))
break return
else -- try to look for it without the file extension else -- try to look for it without the file extension
local files = filesystem.list(item) local files = fs.list(item)
for _, file in pairs(files) do for _, file in pairs(files) do
if args[1] == file:match("(.+)%.[^%.]+$") and not filesystem.isDirectory(item .. file) then -- previous pattern: (.+)%.[^%.]+$
foundfile = true if args[1] == file:match("(.+)%.[^%.]+$") and not fs.isDirectory(item .. file) then
table.remove(args, 1) table.remove(args, 1)
runAsCoroutine(item .. file, table.unpack(args)) runAsCoroutine(item .. file, table.unpack(args))
break return
end end
end end
end end
end end
end
if not foundfile then
print("No such file or command: "..args[1]) print("No such file or command: "..args[1])
end
end end
print(shellcfg["startupMessage"]:format(shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)])) print(shellcfg["startupMessage"]:format(shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)]))
+4 -2
View File
@@ -208,8 +208,8 @@ function _G.read(readHistoryType, prefix, defaultText)
while true do while true do
--ocelot.log(curtext) --ocelot.log(curtext)
termlib.cursorPosX = termlib.cursorPosX - 1 termlib.cursorPosX = termlib.cursorPosX - 1
local args = {event.pull("key_down", 0.5)} local args = {event.pull("key_down", "clipboard", 0.5)}
if args[4] then if args[1] == "key_down" and args[4] then
cursorWhite = true cursorWhite = true
local keycode = args[4] local keycode = args[4]
local key = keyboard.keys[keycode] local key = keyboard.keys[keycode]
@@ -258,6 +258,8 @@ function _G.read(readHistoryType, prefix, defaultText)
end end
termlib.cursorPosX, termlib.cursorPosY = cursorPosX, cursorPosY termlib.cursorPosX, termlib.cursorPosY = cursorPosX, cursorPosY
termlib.write(prefix .. curtext) termlib.write(prefix .. curtext)
elseif args[1] == "clipboard" then
else else
cursorWhite = not cursorWhite cursorWhite = not cursorWhite
end end
+23 -24
View File
@@ -4,39 +4,38 @@ local event = {}
--local ocelot = component.proxy(component.list("ocelot")()) --local ocelot = component.proxy(component.list("ocelot")())
function event.pull(...) function event.pull(...)
local args = {...} local args = {...}
local evtype, timeout local evtypes, timeout = {}, nil
if #args == 0 then for _, arg in pairs(args) do
-- No arguments, wait for any event indefinitely if type(arg) == "number" and not timeout then -- It's a timeout
evtype = nil timeout = arg
timeout = nil else -- It's an event type
elseif #args == 1 then table.insert(evtypes, tostring(arg))
-- If one argument is provided, it could be either the event type or timeout
if type(args[1]) == "number" then
-- It's a timeout
evtype = nil
timeout = args[1]
else
-- It's an event type
evtype = args[1]
timeout = nil
end end
else
-- Both event type and timeout provided
evtype = args[1]
timeout = args[2]
end end
local startTime = computer.uptime() local startTime = computer.uptime()
local result = {}
repeat while true do
-- Check event queue for matching event -- Check event queue for matching event
for i = 1, #evmgr.eventQueue do for i = 1, #evmgr.eventQueue do
if not evtype or evmgr.eventQueue[i][1] == evtype then local foundevent = false
for _, evtype in pairs(evtypes) do
if evtypes[1] then -- event type(s) specified
if evmgr.eventQueue[i][2] == evtype and evmgr.eventQueue[i][1] >= startTime then
foundevent = true
end
else -- event type(s) not specified
if evmgr.eventQueue[i][1] >= startTime then
foundevent = true
end
end
end
if foundevent then
-- Found matching event (or any event if no type specified) -- Found matching event (or any event if no type specified)
result = table.copy(evmgr.eventQueue[i]) local result = table.copy(evmgr.eventQueue[i])
table.remove(evmgr.eventQueue, i) table.remove(evmgr.eventQueue, i)
table.remove(result, 1) -- remove the time of event argument
return table.unpack(result) return table.unpack(result)
end end
end end
@@ -48,7 +47,7 @@ function event.pull(...)
-- Yield to allow other processes to run and more events to be added -- Yield to allow other processes to run and more events to be added
coroutine.yield() coroutine.yield()
until false -- Loop until we find an event or timeout end
end end
return event return event
+4
View File
@@ -0,0 +1,4 @@
-- json.lua by rxi
-- Minified with luamin
-- Original: https://github.com/rxi/json.lua
local a={_version="0.1.2"}local b;local c={["\\"]="\\",["\""]="\"",["\b"]="b",["\f"]="f",["\n"]="n",["\r"]="r",["\t"]="t"}local d={["/"]="/"}for e,f in pairs(c)do d[f]=e end;local function g(h)return"\\"..(c[h]or string.format("u%04x",h:byte()))end;local function i(j)return"null"end;local function k(j,l)local m={}l=l or{}if l[j]then error("circular reference")end;l[j]=true;if rawget(j,1)~=nil or next(j)==nil then local n=0;for e in pairs(j)do if type(e)~="number"then error("invalid table: mixed or invalid key types")end;n=n+1 end;if n~=#j then error("invalid table: sparse array")end;for o,f in ipairs(j)do table.insert(m,b(f,l))end;l[j]=nil;return"["..table.concat(m,",").."]"else for e,f in pairs(j)do if type(e)~="string"then error("invalid table: mixed or invalid key types")end;table.insert(m,b(e,l)..":"..b(f,l))end;l[j]=nil;return"{"..table.concat(m,",").."}"end end;local function p(j)return'"'..j:gsub('[%z\1-\31\\"]',g)..'"'end;local function q(j)if j~=j or j<=-math.huge or j>=math.huge then error("unexpected number value '"..tostring(j).."'")end;return string.format("%.14g",j)end;local r={["nil"]=i,["table"]=k,["string"]=p,["number"]=q,["boolean"]=tostring}b=function(j,l)local s=type(j)local t=r[s]if t then return t(j,l)end;error("unexpected type '"..s.."'")end;function a.encode(j)return b(j)end;local u;local function v(...)local m={}for o=1,select("#",...)do m[select(o,...)]=true end;return m end;local w=v(" ","\t","\r","\n")local x=v(" ","\t","\r","\n","]","}",",")local y=v("\\","/",'"',"b","f","n","r","t","u")local z=v("true","false","null")local A={["true"]=true,["false"]=false,["null"]=nil}local function B(C,D,E,F)for o=D,#C do if E[C:sub(o,o)]~=F then return o end end;return#C+1 end;local function G(C,D,H)local I=1;local J=1;for o=1,D-1 do J=J+1;if C:sub(o,o)=="\n"then I=I+1;J=1 end end;error(string.format("%s at line %d col %d",H,I,J))end;local function K(n)local t=math.floor;if n<=0x7f then return string.char(n)elseif n<=0x7ff then return string.char(t(n/64)+192,n%64+128)elseif n<=0xffff then return string.char(t(n/4096)+224,t(n%4096/64)+128,n%64+128)elseif n<=0x10ffff then return string.char(t(n/262144)+240,t(n%262144/4096)+128,t(n%4096/64)+128,n%64+128)end;error(string.format("invalid unicode codepoint '%x'",n))end;local function L(M)local N=tonumber(M:sub(1,4),16)local O=tonumber(M:sub(7,10),16)if O then return K((N-0xd800)*0x400+O-0xdc00+0x10000)else return K(N)end end;local function P(C,o)local m=""local Q=o+1;local e=Q;while Q<=#C do local R=C:byte(Q)if R<32 then G(C,Q,"control character in string")elseif R==92 then m=m..C:sub(e,Q-1)Q=Q+1;local h=C:sub(Q,Q)if h=="u"then local S=C:match("^[dD][89aAbB]%x%x\\u%x%x%x%x",Q+1)or C:match("^%x%x%x%x",Q+1)or G(C,Q-1,"invalid unicode escape in string")m=m..L(S)Q=Q+#S else if not y[h]then G(C,Q-1,"invalid escape char '"..h.."' in string")end;m=m..d[h]end;e=Q+1 elseif R==34 then m=m..C:sub(e,Q-1)return m,Q+1 end;Q=Q+1 end;G(C,o,"expected closing quote for string")end;local function T(C,o)local R=B(C,o,x)local M=C:sub(o,R-1)local n=tonumber(M)if not n then G(C,o,"invalid number '"..M.."'")end;return n,R end;local function U(C,o)local R=B(C,o,x)local V=C:sub(o,R-1)if not z[V]then G(C,o,"invalid literal '"..V.."'")end;return A[V],R end;local function W(C,o)local m={}local n=1;o=o+1;while 1 do local R;o=B(C,o,w,true)if C:sub(o,o)=="]"then o=o+1;break end;R,o=u(C,o)m[n]=R;n=n+1;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="]"then break end;if X~=","then G(C,o,"expected ']' or ','")end end;return m,o end;local function Y(C,o)local m={}o=o+1;while 1 do local Z,j;o=B(C,o,w,true)if C:sub(o,o)=="}"then o=o+1;break end;if C:sub(o,o)~='"'then G(C,o,"expected string for key")end;Z,o=u(C,o)o=B(C,o,w,true)if C:sub(o,o)~=":"then G(C,o,"expected ':' after key")end;o=B(C,o+1,w,true)j,o=u(C,o)m[Z]=j;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="}"then break end;if X~=","then G(C,o,"expected '}' or ','")end end;return m,o end;local _={['"']=P,["0"]=T,["1"]=T,["2"]=T,["3"]=T,["4"]=T,["5"]=T,["6"]=T,["7"]=T,["8"]=T,["9"]=T,["-"]=T,["t"]=U,["f"]=U,["n"]=U,["["]=W,["{"]=Y}u=function(C,D)local X=C:sub(D,D)local t=_[X]if t then return t(C,D)end;G(C,D,"unexpected character '"..X.."'")end;function a.decode(C)if type(C)~="string"then error("expected argument of type string, got "..type(C))end;local m,D=u(C,B(C,1,w,true))D=B(C,D,w,true)if D<=#C then G(C,D,"trailing garbage")end;return m end;return a