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 = {
["halyde"] = {
["maindir"] = "",
["version"] = "1.7.2",
["version"] = "1.8.0",
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
["directories"] = {
"halyde/apps",
"halyde/apps/helpdb",
"halyde/config",
"halyde/config/generate",
"halyde/core",
"halyde/lib",
"home"
@@ -38,8 +38,8 @@ local agcfg = {
"halyde/apps/mv.lua",
"halyde/apps/rm.lua",
"halyde/config/oslogo.ans",
"halyde/config/shell.cfg",
"halyde/config/startupapps.cfg",
"halyde/config/generate/shell.cfg",
"halyde/config/generate/startupapps.cfg",
"halyde/core/boot.lua",
"halyde/core/cormgr.lua",
"halyde/core/datatools.lua",
@@ -51,6 +51,7 @@ local agcfg = {
"halyde/lib/computer.lua",
"halyde/lib/event.lua",
"halyde/lib/filesystem.lua",
"halyde/lib/json.lua",
"halyde/lib/raster.lua"
}
},
+5 -4
View File
@@ -1,10 +1,10 @@
Ahome/
Ahalyde/lib/
Ahalyde/core/
Ahalyde/config/
Ahalyde/config/generate/
Ahalyde/apps/helpdb/
Ahalyde/apps/
V1.7.2
V1.8.0
Ainit.lua
Ahalyde/apps/helpdb/cat.txt
Ahalyde/apps/helpdb/cd.txt
@@ -31,8 +31,8 @@ Ahalyde/apps/mkdir.lua
Ahalyde/apps/mv.lua
Ahalyde/apps/rm.lua
Ahalyde/config/oslogo.ans
Ahalyde/config/shell.cfg
Ahalyde/config/startupapps.cfg
Ahalyde/config/generate/shell.cfg
Ahalyde/config/generate/startupapps.cfg
Ahalyde/core/boot.lua
Ahalyde/core/cormgr.lua
Ahalyde/core/datatools.lua
@@ -44,4 +44,5 @@ Ahalyde/lib/component.lua
Ahalyde/lib/computer.lua
Ahalyde/lib/event.lua
Ahalyde/lib/filesystem.lua
Ahalyde/lib/json.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 filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
_G._OSVERSION = "Halyde 1.7.2"
_G._OSVERSION = "Halyde 1.8.0"
_G._OSLOGO = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
@@ -85,4 +85,13 @@ preload("computer")
--assert(handle:write("Bazinga!"))
--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")
+4 -4
View File
@@ -5,6 +5,7 @@ _G.cormgr.corList = {}
local component = import("component")
local filesystem = import("filesystem")
local json = import("json")
local gpu = component.proxy(component.list("gpu")())
function _G.cormgr.loadCoroutine(path, ...)
@@ -55,14 +56,13 @@ local function runCoroutines()
end
end
local handle = filesystem.open("/halyde/config/startupapps.cfg", "r")
local data = ""
local tmpdata
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
for line in data:gmatch("([^\n]*)\n?") do
handle:close()
for _, line in ipairs(json.decode(data)) do
if line ~= "" then
--[[ if _G.print then
print(line)
+6 -7
View File
@@ -12,13 +12,12 @@ keyboard.altDown = false
while true do
local args
repeat
args = {computer.pullSignal(0)}
if args and args[1] then
--ocelot.log("Sending signal "..args..","..computer.uptime())
args = {computer.uptime(), computer.pullSignal(0)}
if args and args[2] then
table.insert(evmgr.eventQueue, args)
if keyboard then
if args[1] == "key_down" then
local keycode = args[4]
if args[2] == "key_down" then
local keycode = args[5]
local key = keyboard.keys[keycode]
if key == "lcontrol" then
keyboard.ctrlDown = true
@@ -30,8 +29,8 @@ while true do
end
cormgr.corList[#cormgr.corList] = nil
end
elseif args[1] == "key_up" then
local keycode = args[4]
elseif args[2] == "key_up" then
local keycode = args[5]
local key = keyboard.keys[keycode]
if key == "lcontrol" then
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")
local event = import("event")
local filesystem = import("filesystem")
local component = import("component")
local gpu = component.proxy(component.list("gpu")())
@@ -51,39 +58,36 @@ function _G.shell.run(command)
end
end
-- execute the program
local foundfile = false
local PATH = table.copy(shellcfg.path)
table.insert(PATH, shell.workingDirectory)
if not args[1] then
return
end
if filesystem.exists(args[1]) and not filesystem.isDirectory(args[1]) then
foundfile = true
if fs.exists(args[1]) and not fs.isDirectory(args[1]) then
local path = args[1]
table.remove(args, 1)
runAsCoroutine(path, table.unpack(args))
else
for _, item in pairs(shellcfg["path"]) do
if filesystem.exists(item..args[1]) and not filesystem.isDirectory(item .. args[1]) then
foundfile = true
local path = item..args[1]
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)
runAsCoroutine(path, table.unpack(args))
break
return
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
if args[1] == file:match("(.+)%.[^%.]+$") and not filesystem.isDirectory(item .. file) then
foundfile = true
-- previous pattern: (.+)%.[^%.]+$
if args[1] == file:match("(.+)%.[^%.]+$") and not fs.isDirectory(item .. file) then
table.remove(args, 1)
runAsCoroutine(item .. file, table.unpack(args))
break
return
end
end
end
end
end
if not foundfile then
print("No such file or command: "..args[1])
end
end
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
--ocelot.log(curtext)
termlib.cursorPosX = termlib.cursorPosX - 1
local args = {event.pull("key_down", 0.5)}
if args[4] then
local args = {event.pull("key_down", "clipboard", 0.5)}
if args[1] == "key_down" and args[4] then
cursorWhite = true
local keycode = args[4]
local key = keyboard.keys[keycode]
@@ -258,6 +258,8 @@ function _G.read(readHistoryType, prefix, defaultText)
end
termlib.cursorPosX, termlib.cursorPosY = cursorPosX, cursorPosY
termlib.write(prefix .. curtext)
elseif args[1] == "clipboard" then
else
cursorWhite = not cursorWhite
end
+23 -24
View File
@@ -4,39 +4,38 @@ local event = {}
--local ocelot = component.proxy(component.list("ocelot")())
function event.pull(...)
local args = {...}
local evtype, timeout
local evtypes, timeout = {}, nil
if #args == 0 then
-- No arguments, wait for any event indefinitely
evtype = nil
timeout = nil
elseif #args == 1 then
-- 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
for _, arg in pairs(args) do
if type(arg) == "number" and not timeout then -- It's a timeout
timeout = arg
else -- It's an event type
table.insert(evtypes, tostring(arg))
end
else
-- Both event type and timeout provided
evtype = args[1]
timeout = args[2]
end
local startTime = computer.uptime()
local result = {}
repeat
while true do
-- Check event queue for matching event
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)
result = table.copy(evmgr.eventQueue[i])
local result = table.copy(evmgr.eventQueue[i])
table.remove(evmgr.eventQueue, i)
table.remove(result, 1) -- remove the time of event argument
return table.unpack(result)
end
end
@@ -48,7 +47,7 @@ function event.pull(...)
-- Yield to allow other processes to run and more events to be added
coroutine.yield()
until false -- Loop until we find an event or timeout
end
end
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