From a9cf5b2da3ce20457b2e68ad610320ae8f28b76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 24 Apr 2014 21:35:17 +0200 Subject: [PATCH] Somewhat less broken besh, but something's still not right... --- .../opencomputers/loot/BetterShell/besh.lua | 66 ++++++++++++++++--- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/BetterShell/besh.lua b/src/main/resources/assets/opencomputers/loot/BetterShell/besh.lua index f118d725c..0d25c7262 100644 --- a/src/main/resources/assets/opencomputers/loot/BetterShell/besh.lua +++ b/src/main/resources/assets/opencomputers/loot/BetterShell/besh.lua @@ -11,7 +11,11 @@ local term = require("term") local text = require("text") local unicode = require("unicode") -local function expandParam(param) +-- Avoid scoping issues by simple forward declaring all methods... it's +-- not a beauty, but it works :P +local expand, expandCmd, expandMath, expandParam, parseCommand, parseCommands + +expandParam = function(param) local par, word, op = nil, nil, nil for _, oper in ipairs{':%-', '%-', ':=', '=', ':%?','%?', ':%+', '%+'} do par, word = param:match("(.-)"..oper.."(.*)") @@ -86,11 +90,11 @@ local function expandParam(param) end end -local function expandCmd(cmd) +expandCmd = function(cmd) return cmd end -local function expandMath(expr) +expandMath = function(expr) local success, reason = load("return "..expr, os.getenv("SHELL"), 't', {}) if success then return success() @@ -99,7 +103,7 @@ local function expandMath(expr) end end -local function expand(token) +expand = function(token) local expr = {} local matchStack = {} local escaped = false @@ -210,7 +214,7 @@ local function expand(token) return table.concat(endToken) end -local function parseCommand(tokens) +parseCommand = function(tokens) if #tokens == 0 then return end @@ -263,14 +267,15 @@ local function parseCommand(tokens) return nil, state end end - return program, args, input, output, mode end -local function parseCommands(command) +parseCommands = function(command) local tokens, reason = text.tokenize(command) if not tokens then return nil, reason + elseif #tokens == 0 then + return true end local commands, command = {}, {} @@ -468,5 +473,48 @@ local function execute(command, env, ...) return table.unpack(result, 1, result.n) end -local env = setmetatable({os=setmetatable({execute=execute}, {__index=os})}, {__index=_ENV}) -shell.execute("/bin/sh", env, ...) +local args, options = shell.parse(...) +local history = {} + +if #args == 0 and (io.input() == io.stdin or options.i) and not options.c then + -- interactive shell. + while true do + if not term.isAvailable() then -- don't clear unless we lost the term + while not term.isAvailable() do + event.pull("term_available") + end + term.clear() + end + while term.isAvailable() do + local foreground = component.gpu.setForeground(0xFF0000) + term.write(expand(os.getenv("PS1") or "$ ")) + component.gpu.setForeground(foreground) + local command = term.read(history) + if not command then + term.write("exit\n") + return -- eof + end + while #history > 10 do + table.remove(history, 1) + end + command = text.trim(command) + if command == "exit" then + return + elseif command ~= "" then + local result, reason = execute(command) + if not result then + io.stderr:write((tostring(reason) or "unknown error").. "\n") + elseif term.getCursor() > 1 then + term.write("\n") + end + end + end + end +else + -- execute command. + local result = table.pack(execute(...)) + if not result[1] then + error(result[2]) + end + return table.unpack(result, 2) +end