v0.6.0 - Added shell parser, echo command and some other minor tweaks.

This commit is contained in:
TheWahlolly
2025-04-26 12:38:05 +03:00
parent d220b9d648
commit 64a761fdde
7 changed files with 90 additions and 11 deletions
+7
View File
@@ -0,0 +1,7 @@
local args = {...}
local concatText = args[1]
table.remove(args, 1)
for _, item in pairs(args) do
concatText = concatText .. " " .. item
end
print(concatText)
+4 -2
View File
@@ -1,6 +1,8 @@
local shellcfg = { local shellcfg = {
["startupMessage"] = "\n │\n │ ".._OSVERSION..'\n │ Welcome! Type "help" to get started.\n │\n ', -- message shown on startup ["startupMessage"] = "\n │\n │ ".._OSVERSION.." running on ".._VERSION..'\n │ Welcome! Type "help" to get started.\n │\n ', -- message shown on startup
["prompt"] = "\x1b[92m%s > \x1b[0m" -- shell prompt, %s will be replaced with working directory. example: "%s > " turns to "/current/working/directory > " ["prompt"] = "\x1b[92m%s > \x1b[0m", -- shell prompt, %s will be replaced with working directory. example: "%s > " turns to "/current/working/directory > "
["path"] = { -- default locations where programs will be run from
"/halyde/apps/"}
} }
return shellcfg return shellcfg
+3 -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 0.5.1" _G._OSVERSION = "Halyde 0.6.0"
function _G.import(module, ...) function _G.import(module, ...)
local args = table.pack(...) local args = table.pack(...)
@@ -12,6 +12,8 @@ function _G.import(module, ...)
end end
elseif filesystem.exists("/halyde/lib/"..module..".lua") then elseif filesystem.exists("/halyde/lib/"..module..".lua") then
modulepath = "/halyde/lib/"..module..".lua" modulepath = "/halyde/lib/"..module..".lua"
elseif shell and shell.workingDirectory and filesystem.exists(shell.workingDirectory..module) then
modulepath = shell.workingDirectory..module
end end
assert(modulepath, "module not found\npossible locations:\n/halyde/lib/"..module..".lua") assert(modulepath, "module not found\npossible locations:\n/halyde/lib/"..module..".lua")
local handle = filesystem.open(modulepath) local handle = filesystem.open(modulepath)
+65 -3
View File
@@ -1,10 +1,72 @@
local shellcfg = import("/halyde/config/shell.cfg") local shellcfg = import("/halyde/config/shell.cfg")
import("termlib") import("termlib")
local event = import("event") local event = import("event")
local ocelot = component.proxy(component.list("ocelot")())
local filesystem = import("filesystem")
_G.shell = {} _G.shell = {}
_G.shell.workingDirectory = "/" _G.shell.workingDirectory = "/"
local function parseCommand(command)
checkArg(1, command, "string")
local gm, result, args, trimmedCommand = command:gmatch('[^ ]+'), nil, {}, command
while true do
result = gm()
if not result then
break
end
if result:find('"') then
local location = trimmedCommand:find('"')
local argBefore = result:sub(1, result:find('"') - 1) -- edge case where there is no space before the quote, get the argument there
if argBefore and argBefore ~= "" then
table.insert(args, argBefore)
end
trimmedCommand = trimmedCommand:sub(location + 1)
if trimmedCommand:find('"') then
table.insert(args, trimmedCommand:sub(1, trimmedCommand:find('"') - 1))
trimmedCommand = trimmedCommand:sub(trimmedCommand:find('"') + 1)
gm = trimmedCommand:gmatch('[^ ]+')
else
print("\27[91mmalformed shell command")
return
end
else
table.insert(args, result)
end
end
-- execute the program
local foundfile = false
if filesystem.exists(args[1]) then
foundfile = true
local path = args[1]
table.remove(args, 1)
import(path, table.unpack(args))
else
for _, item in pairs(shellcfg["path"]) do
if filesystem.exists(item..args[1]) then
foundfile = true
local path = item..args[1]
table.remove(args, 1)
import(path, table.unpack(args))
break
else -- try to look for it without the file extension
local files = filesystem.list(item)
for _, file in pairs(files) do
if args[1] == file:match("(.+)%.[^%.]+$") then
foundfile = true
table.remove(args, 1)
import(item..file, table.unpack(args))
break
end
end
end
end
end
if not foundfile then
print("no such file or command: "..args[1])
end
end
print(shellcfg["startupMessage"]) print(shellcfg["startupMessage"])
while true do while true do
coroutine.yield() coroutine.yield()
@@ -12,7 +74,7 @@ while true do
print(shellcfg["prompt"]:format(shell.workingDirectory),false) print(shellcfg["prompt"]:format(shell.workingDirectory),false)
-- termlib.cursorPosX = #(shell.workingDirectory .. " > ") -- termlib.cursorPosX = #(shell.workingDirectory .. " > ")
-- termlib.cursorPosY = termlib.cursorPosY - 1 -- termlib.cursorPosY = termlib.cursorPosY - 1
read() local shellCommand = read()
termlib.cursorPosX = 1 ocelot.log("parsing "..shellCommand)
print("no shell parser yet") parseCommand(shellCommand)
end end
+10 -2
View File
@@ -11,7 +11,7 @@ local filesystem = {}
function filesystem.processPath(path) -- returns the address and absolute path of a filesystem path as well as sanitizing it function filesystem.processPath(path) -- returns the address and absolute path of a filesystem path as well as sanitizing it
checkArg(1, path, "string") checkArg(1, path, "string")
absPath = path:gsub("/+", "/"):gsub("/$", "") absPath = path:gsub("/+", "/")
local address = nil local address = nil
if absPath:find("^/mnt/.../") then if absPath:find("^/mnt/.../") then
address = component.get(path:sub(6,8)) address = component.get(path:sub(6,8))
@@ -66,4 +66,12 @@ function filesystem.open(path, mode) -- opens a file and returns its handle
return properHandle return properHandle
end end
return(filesystem) function filesystem.list(path)
checkArg(1, path, "string")
local address, absPath = filesystem.processPath(path)
if not address then
return false
end
return component.invoke(address, "list", absPath)
end
return(filesystem)
View File
+1 -3
View File
@@ -2,7 +2,6 @@ local event = import("event")
--local keyboard = import("keyboard") --local keyboard = import("keyboard")
local gpu = component.proxy(component.list("gpu")()) -- replace with component.gpu once implemented local gpu = component.proxy(component.list("gpu")()) -- replace with component.gpu once implemented
local ocelot = component.proxy(component.list("ocelot")())
_G.termlib = {} _G.termlib = {}
termlib.cursorPosX = 1 termlib.cursorPosX = 1
termlib.cursorPosY = 1 termlib.cursorPosY = 1
@@ -41,7 +40,6 @@ gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor) gpu.setBackground(defaultBackgroundColor)
local function scrollDown() local function scrollDown()
ocelot.log("scrolling")
if gpu.copy(0,1,width,height,0,-1) then if gpu.copy(0,1,width,height,0,-1) then
gpu.set(1,height,string.rep(" ",width)) gpu.set(1,height,string.rep(" ",width))
termlib.cursorPosY=height termlib.cursorPosY=height
@@ -183,7 +181,7 @@ function _G.read()
end end
end end
termlib.cursorPosX, termlib.cursorPosY = cursorPosX, cursorPosY termlib.cursorPosX, termlib.cursorPosY = cursorPosX, cursorPosY
if curtext == "" then print(" ", false) else print(curtext, false) end print(curtext, false)
else else
cursorWhite = not cursorWhite cursorWhite = not cursorWhite
end end