204 lines
5.4 KiB
Lua
204 lines
5.4 KiB
Lua
![]() |
local bsh = {}
|
||
|
local component = require("component")
|
||
|
local computer = require("computer")
|
||
|
local event = require("event")
|
||
|
local fs = require("filesystem")
|
||
|
local package = require("package")
|
||
|
_G.ExecPath = "/sbin/?.lua;/bin/?.lua"
|
||
|
|
||
|
if fs.exists("/etc/motd") then
|
||
|
local motd_h = fs.open("/etc/motd", "r")
|
||
|
print(fs.read(motd_h))
|
||
|
fs.close(motd_h)
|
||
|
end
|
||
|
|
||
|
print("\n")
|
||
|
|
||
|
-- BUG: when in /bin directory, running something tries to run /binhello.lua
|
||
|
-- FEAT: autofill slashes, and .lua
|
||
|
-- FEAT: handle ..
|
||
|
|
||
|
bsh.running = true
|
||
|
local cwd = "/home/"
|
||
|
|
||
|
local function keyin(timeout)
|
||
|
while true do
|
||
|
local _,_,ascii,code,_ = event.pull("key_down",timeout)
|
||
|
return ascii,code
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function bsh.split(str)
|
||
|
local words = {}
|
||
|
for word in str:gmatch("%S+") do
|
||
|
table.insert(words, word)
|
||
|
end
|
||
|
return words
|
||
|
end
|
||
|
|
||
|
function bsh.is_in_arr(arr,elem)
|
||
|
for i in ipairs(arr) do
|
||
|
if tostring(arr[i]) == tostring(elem) then
|
||
|
return true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
function bsh.command(buffer)
|
||
|
if #buffer == 0 then
|
||
|
return
|
||
|
end
|
||
|
local command = bsh.split(buffer)
|
||
|
if command[1] == "ls" then
|
||
|
local cwdls
|
||
|
if command[2] == nil then
|
||
|
cwdls = fs.getlisting(cwd)
|
||
|
else
|
||
|
cwdls = fs.getlisting(command[2])
|
||
|
end
|
||
|
if cwdls ~= nil then
|
||
|
for i = 1, #cwdls do
|
||
|
print(cwdls[i] .. " ")
|
||
|
end
|
||
|
else
|
||
|
print("(Nothing here!)")
|
||
|
end
|
||
|
print("\r\n")
|
||
|
elseif command[1] == "cd" then
|
||
|
if command[2] == nil then
|
||
|
error("no argument")
|
||
|
else
|
||
|
cwd = command[2]
|
||
|
end
|
||
|
elseif command[1] == "clear" then
|
||
|
local w,h=component.gpu.getResolution()
|
||
|
component.gpu.fill(1,1,w,h," ")
|
||
|
component.gpu.setCursor(2,1)
|
||
|
elseif command[1] == "exit" then
|
||
|
bsh.running = false
|
||
|
else -- execute file, this sucks tho
|
||
|
local location = command[1]
|
||
|
local s,_ = pcall(fs.loadfile,location)
|
||
|
-- is in cwd?
|
||
|
if not s then
|
||
|
if bsh.is_in_arr(fs.getlisting(cwd),command[1]) then
|
||
|
location = cwd .. command[1]
|
||
|
else
|
||
|
-- no, check path
|
||
|
local a = package.search(command[1],ExecPath)
|
||
|
if a ~= false then
|
||
|
location = a
|
||
|
else
|
||
|
error("command not found")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local a = fs.loadfile(location)
|
||
|
a(command)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function prompt()
|
||
|
print(cwd .." #> ")
|
||
|
end
|
||
|
|
||
|
print("bsh v3\n")
|
||
|
|
||
|
local buffer = ""
|
||
|
local gpu = component.gpu
|
||
|
|
||
|
prompt()
|
||
|
|
||
|
local cursor = "█"
|
||
|
local cursorOnOff = 1
|
||
|
local history = {}
|
||
|
local history_index = 1
|
||
|
|
||
|
while bsh.running do
|
||
|
local nextkeycode, code = keyin()
|
||
|
local charAtCurLocation = " "
|
||
|
local cur = gpu.getCursor()
|
||
|
--print(nextkeycode,"=",code," ")
|
||
|
|
||
|
if nextkeycode == nil and code == nil then
|
||
|
-- timeout reached, invert cursor
|
||
|
cursorOnOff = cursorOnOff * -1
|
||
|
if cursorOnOff == 1 then
|
||
|
charAtCurLocation = gpu.get(cur.x,cur.y)
|
||
|
gpu.set(cur.x,cur.y,cursor)
|
||
|
else
|
||
|
gpu.set(cur.x,cur.y,charAtCurLocation)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if nextkeycode == 0 or nextkeycode == nil then
|
||
|
local preBuffer=buffer
|
||
|
if code == 42 then -- shift
|
||
|
-- ignore
|
||
|
elseif code == 200 then -- up
|
||
|
if history[history_index] then
|
||
|
buffer = history[history_index]
|
||
|
history_index = history_index - 1
|
||
|
gpu.setCursor(1)
|
||
|
prompt()
|
||
|
for i=1,#preBuffer do print(" ") end
|
||
|
gpu.setCursor(1)
|
||
|
prompt()
|
||
|
print(buffer)
|
||
|
end
|
||
|
elseif code == 208 then -- down
|
||
|
if history[history_index+1] then
|
||
|
history_index = history_index + 2
|
||
|
buffer = history[history_index]
|
||
|
gpu.setCursor(1)
|
||
|
prompt()
|
||
|
for i=1,#preBuffer do print(" ") end
|
||
|
gpu.setCursor(1)
|
||
|
prompt()
|
||
|
print(buffer)
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
gpu.set(cur.x,cur.y,charAtCurLocation)
|
||
|
local nextkey = string.char(nextkeycode)
|
||
|
|
||
|
if nextkeycode == 13 then --enter
|
||
|
table.insert(history, buffer)
|
||
|
history_index = #history
|
||
|
if cursorOnOff ~= 1 then
|
||
|
gpu.set(cur.x,cur.y,charAtCurLocation)
|
||
|
end
|
||
|
print("\n")
|
||
|
local success, reason = xpcall(bsh.command, function(a)
|
||
|
return {a, debug.traceback()}
|
||
|
end, buffer)
|
||
|
|
||
|
if not success then
|
||
|
if reason then
|
||
|
print(reason[1].."\n\n")
|
||
|
component.gpu.setForeground(0xff3333)
|
||
|
print(reason[2])
|
||
|
component.gpu.setForeground(0xffffff)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
buffer = ""
|
||
|
nextkeycode = nil
|
||
|
print("\n")
|
||
|
prompt()
|
||
|
elseif nextkeycode == 8 then --backsp
|
||
|
if #buffer ~= 0 then
|
||
|
buffer = buffer:sub(1, -2)
|
||
|
gpu.moveCursor(-1)
|
||
|
print(" ")
|
||
|
gpu.moveCursor(-1)
|
||
|
end
|
||
|
else
|
||
|
buffer = buffer .. nextkey
|
||
|
print(nextkey)
|
||
|
end
|
||
|
end
|
||
|
end
|