Screen = require("screen") fontsize = 8 fontw = 8 termline = "" termbottom = fontsize state = 1 task = nil history = {} histpos = #history function _init() scrn = Screen:new((sys.env("ENGINE") or "System") .. " Shell", 10, 4) scrnw, scrnh = view.size(scrn.mainvp) spare = image.new(scrnw, scrnh, 4) font = text.loadfont("Victoria.8b") scrn:palette(4, 10, 5, 5) scrn:palette(5, 5, 10, 5) scrn:palette(6, 5, 7, 10) scrn:palette(7, 10, 8, 5) scrn:palette(0, 10, 11, 12) scrn:palette(3, 5, 10, 15) scrn:palette(1, 0, 0, 0) scrn:palette(2, 15, 15, 15) scrn:colors(0, 0) if sys.env("ENGINE_VERSION") then out("System version " .. sys.env("ENGINE_VERSION") .. "\n\n") out("Modifications made by Zdrwiiu \n\n") end end function _step() local inp = input.text() if string.find(inp, "\t") ~= nil then input.text(tabcomplete(inp, fs.list())) end if string.find(inp, "\n") ~= nil then submit(string.gsub(inp, "\n", "")) end if state == 0 then local btn = input.gamepad() if lastinp == inp and lastbtn == 0 and btn > 0 then if btn & 4 > 0 then histpos = histpos - 1 if histpos < 1 then histpos = 1 end input.text(history[histpos]) end if btn & 8 > 0 then histpos = histpos + 1 if histpos > #history then histpos = #history + 1 input.text("") end input.text(history[histpos]) end end lastbtn = btn out("") elseif state == 1 then if task == nil then out(fs.cd() .. "> ") state = 0 else out(sys.readfromchild(task)) out(sys.errorfromchild(task)) if sys.childrunning(task) then if (input.hotkey() == "c") then sys.killchild(task) end else sys.forgetchild(task) task = nil end end end lastinp = inp scrn:step() end function submit(line) local cmd = "" local args = parsecmd(line) out(line .. "\n") input.text("") input.clearhistory() if state == 0 then cmd = table.remove(args, 1) if cmd then if searchhistory(line) then table.remove(history, searchhistory(line)) end table.insert(history, line) end histpos = #history + 1 if (cmd == "endcli") then sys.exit(0) elseif (cmd == "cd") then if not fs.cd(args[1]) then out("Unable to change directory to " .. args[1] .. "\n") end elseif (cmd == "clear") then gfx.cls() termbottom = 0 out("\n") elseif (cmd == "help") then out("Builtin commands: cd, clear, endcli, help\n\nsys:cmd/\n") task = sys.startchild(_DRIVE .. "cmd/dir.lua", {_DRIVE .. "cmd/"}) elseif cmd and cmd ~= "" then if task == nil then task = sys.startchild(cmd, args) end if task == nil then task = sys.startchild(cmd .. ".lua", args) end if task == nil then task = sys.startchild("user:cmd/" .. cmd, args) end if task == nil then task = sys.startchild("user:cmd/" .. cmd .. ".lua", args) end if task == nil then task = sys.startchild("sys:cmd/" .. cmd, args) end if task == nil then task = sys.startchild("sys:cmd/" .. cmd .. ".lua", args) end if task == nil then out("Unknown command " .. cmd .. "\n") end end state = 1 elseif state == 1 then if task ~= nil then sys.writetochild(task, line .. "\n") end end end function out(data) local w, h local txt = input.text() local pos, sel = input.cursor() termline = termline .. wrap(data, scrnw / fontw) gfx.fgcolor(0) gfx.bar(0, termbottom - fontsize, scrnw, scrnh) gfx.fgcolor(1) -- repeat w, h = text.draw(termline, font, 0, termbottom - fontsize) h = termbottom - fontsize + h if h > scrnh then scroll(h - scrnh) text.draw(termline, font, 0, termbottom - fontsize) end while string.find(termline, "\n") ~= nil do termline = string.sub(termline, string.find(termline, "\n") + 1) termbottom = termbottom + fontsize end if state == 1 then sys.stepinterval(64) else sys.stepinterval(-1) end -- until string.find(termline, "\n") == nil text.draw(txt, font, w, termbottom - fontsize) gfx.fgcolor(3) text.draw(string.sub(txt, 0, pos) .. "\x7f", font, w, termbottom - fontsize) text.draw(string.sub(txt, 0, pos + sel), font, w, termbottom - fontsize) if sel == 0 then gfx.fgcolor(2) else gfx.fgcolor(1) end text.draw(string.sub(txt, 0, pos + 1), font, w, termbottom - fontsize) gfx.fgcolor(1) text.draw(string.sub(txt, 0, pos), font, w, termbottom - fontsize) end function scroll(amount) image.copy(spare, 0, 0, 0, 0, scrnw, scrnh) gfx.cls() image.draw(spare, 0, -amount, 0, 0, scrnw, scrnh) termbottom = termbottom - amount end function wrap(txt, width) local col = 0 local out = "" for i = 1, #txt do out = out .. string.sub(txt, i, i) col = col + 1 if string.sub(txt, i, i) == "\n" then col = 0 end if col == width then out = out .. "\n" col = 0 end end return out end function parsecmd(line) local args = {} local arg = nil local term = " " local esc = false for i = 1, #line do local char = string.sub(line, i, i) if esc then arg = arg .. char esc = false elseif char == term then if arg ~= nil then table.insert(args, arg) arg = nil term = " " end elseif term == " " and (char == '"' or char == "'") then term = char arg = arg or "" else arg = arg or "" if char == "\\" then esc = true else arg = arg .. char end end end if arg ~= nil then table.insert(args, arg) end return args end function searchhistory(line) for i = 1, #history do if history[i] == line then return i end end return nil end function tabcomplete(line, options) if not options then return line end local tabpos = string.find(line, "\t") if not tabpos then return line end local rest = string.sub(line, tabpos + 1) local args = parsecmd(string.sub(line, 1, tabpos - 1)) local arg = table.remove(args) if not arg then return line end for i = 1, #options do local opt = options[i] if string.lower(string.sub(opt, 1, #arg)) == string.lower(arg) then arg = opt end end table.insert(args, arg) line = "" for i = 1, #args do arg = args[i] line = line .. string.gsub(arg, " ", "\\ ") .. " " end line = line .. rest return line end