return function(con) local sh = { prompt = function() return '>' end, runs = true, env = { code = 0, path = 'sysapps:apps', } } function sh:which(cmd) local file = cmd or '' if file:sub(-4) ~= '.lua' then file = file.. '.lua' end if fsHas(file) then return '', file end for path in self.env.path:gmatch '[^:]+' do if fsHas(path..'/'..file) then return path, '/'..file end end end function sh:parseArgs(ln) local iq, buf, args = false, '', {} local qt, esc = nil, false ln = ln:gsub('%$(%S+)%s*=%s*(.*)$', function(k, v) env[k] = self:parseArgs(v)[1] return '' end) -- helper function local function psh() if buf:sub(1,1) == '$' then buf = tostring(self.env[buf:sub(2)] or '') end if #buf > 0 then table.insert(args, buf) end buf, qt = '', nil end for i = 1, #ln + 1 do local v = ln:sub(i, i) if ((v == ' ' or v == '\n' or v == '\t') and not iq) or v == '' then psh() elseif esc then esc, buf = false, buf.. v elseif v == '\\' then esc = true elseif (not qt or qt == v) and (v == '"' or v == "'") then psh() qt, iq = v, not iq else buf = buf.. v end end return args end function sh:run() return 'TODO' end function sh:loop() await(function() con.print(self:prompt()) local ln = con.getln() con.down() local res = self:run(ln) if res then con.println(res) end return not self.runs end) end return sh end