mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-31 15:43:00 +00:00 
			
		
		
		
	transition to kernel
This commit is contained in:
		
							
								
								
									
										72
									
								
								startup
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								startup
									
									
									
									
									
								
							| @@ -1,9 +1,18 @@ | |||||||
|  | local colors   = _G.colors | ||||||
|  | local os       = _G.os | ||||||
|  | local settings = _G.settings | ||||||
|  | local term     = _G.term | ||||||
|  |  | ||||||
| local bootOptions = { | local bootOptions = { | ||||||
|   { prompt = 'Default Shell', file = '/sys/boot/default.boot' }, |   { prompt = os.version() }, | ||||||
|   { prompt = 'Opus'         , file = '/sys/boot/opus.boot' }, |   { prompt = 'Opus'         , args = { '/sys/boot/opus.boot' } }, | ||||||
| --  { prompt = 'TLCO'         , file = '/sys/boot/tlco.boot' }, |   { prompt = 'Opus Shell'   , args = { '/sys/boot/opus.boot', 'sys/apps/shell' } }, | ||||||
| } | } | ||||||
| local bootOption = 2 | local bootOption = 2 | ||||||
|  | if settings then | ||||||
|  |   settings.load('.settings') | ||||||
|  |   bootOption = tonumber(settings.get('opus.boot_option') or 2) or 2 | ||||||
|  | end | ||||||
|  |  | ||||||
| local function startupMenu() | local function startupMenu() | ||||||
|   while true do |   while true do | ||||||
| @@ -16,20 +25,51 @@ local function startupMenu() | |||||||
|     end |     end | ||||||
|     print('') |     print('') | ||||||
|     term.write('> ') |     term.write('> ') | ||||||
|     local ch = tonumber(read()) |     local ch = tonumber(_G.read()) | ||||||
|     if ch and bootOptions[ch] then |     if ch and bootOptions[ch] then | ||||||
|       return ch |       return ch | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   term.clear() | end | ||||||
|   term.setCursorPos(1, 1) |  | ||||||
|  | local function splash() | ||||||
|  |   local w, h = term.current().getSize() | ||||||
|  |  | ||||||
|  |   term.setTextColor(colors.white) | ||||||
|  |   if not term.isColor() then | ||||||
|  |     local str = 'Opus OS' | ||||||
|  |     term.setCursorPos((w - #str) / 2, h / 2) | ||||||
|  |     term.write(str) | ||||||
|  |   else | ||||||
|  |     term.setBackgroundColor(colors.black) | ||||||
|  |     term.clear() | ||||||
|  |     local opus = { | ||||||
|  |       'fffff00', | ||||||
|  |       'ffff07000', | ||||||
|  |       'ff00770b00 4444', | ||||||
|  |       'ff077777444444444', | ||||||
|  |       'f07777744444444444', | ||||||
|  |       'f0000777444444444', | ||||||
|  |       '070000111744444', | ||||||
|  |       '777770000', | ||||||
|  |       '7777000000', | ||||||
|  |       '70700000000', | ||||||
|  |       '077000000000', | ||||||
|  |     } | ||||||
|  |     for k,line in ipairs(opus) do | ||||||
|  |       term.setCursorPos((w - 18) / 2, k + (h - #opus) / 2) | ||||||
|  |       term.blit(string.rep(' ', #line), string.rep('a', #line), line) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   local str = 'Press any key for menu' | ||||||
|  |   term.setCursorPos((w - #str) / 2, h) | ||||||
|  |   term.write(str) | ||||||
| end | end | ||||||
|  |  | ||||||
| term.clear() | term.clear() | ||||||
| term.setCursorPos(1, 1) | splash() | ||||||
| print('Starting OS') |  | ||||||
| print() |  | ||||||
| print('Press any key for menu') |  | ||||||
| local timerId = os.startTimer(1.5) | local timerId = os.startTimer(1.5) | ||||||
| while true do | while true do | ||||||
|   local e, id = os.pullEvent() |   local e, id = os.pullEvent() | ||||||
| @@ -38,8 +78,18 @@ while true do | |||||||
|   end |   end | ||||||
|   if e == 'char' then |   if e == 'char' then | ||||||
|     bootOption = startupMenu() |     bootOption = startupMenu() | ||||||
|  |     if settings then | ||||||
|  |       settings.set('opus.boot_option', bootOption) | ||||||
|  |       settings.save('.settings') | ||||||
|  |     end | ||||||
|     break |     break | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| os.run(getfenv(1), bootOptions[bootOption].file) | term.clear() | ||||||
|  | term.setCursorPos(1, 1) | ||||||
|  | if bootOptions[bootOption].args then | ||||||
|  |   os.run(_G.getfenv(1), table.unpack(bootOptions[bootOption].args)) | ||||||
|  | else | ||||||
|  |   print(bootOptions[bootOption].prompt) | ||||||
|  | end | ||||||
|   | |||||||
| @@ -154,8 +154,10 @@ function Event.pullEvents(...) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   repeat |   repeat | ||||||
|     local e = Event.pullEvent() |     Event.pullEvent() | ||||||
|   until e[1] == 'terminate' |   until Event.terminate | ||||||
|  |  | ||||||
|  |   Event.terminate = false | ||||||
| end | end | ||||||
|  |  | ||||||
| function Event.exitPullEvents() | function Event.exitPullEvents() | ||||||
| @@ -203,11 +205,12 @@ function Event.pullEvent(eventType) | |||||||
|   while true do |   while true do | ||||||
|     local e = { os.pullEventRaw() } |     local e = { os.pullEventRaw() } | ||||||
|  |  | ||||||
|  |     Event.terminate = Event.terminate or e[1] == 'terminate' | ||||||
|  |  | ||||||
|     processHandlers(e[1]) |     processHandlers(e[1]) | ||||||
|     processRoutines(table.unpack(e)) |     processRoutines(table.unpack(e)) | ||||||
|  |  | ||||||
|     if Event.terminate or e[1] == 'terminate' then |     if Event.terminate then | ||||||
|       Event.terminate = false |  | ||||||
|       return { 'terminate' } |       return { 'terminate' } | ||||||
|     end |     end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -55,12 +55,13 @@ local function loadUrl(url) | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | -- Add require and package to the environment | ||||||
| local function requireWrapper(env) | local function requireWrapper(env) | ||||||
|  |  | ||||||
|   local function standardSearcher(modname) |   local function standardSearcher(modname) | ||||||
|     if package.loaded[modname] then |     if env.package.loaded[modname] then | ||||||
|       return function() |       return function() | ||||||
|         return package.loaded[modname] |         return env.package.loaded[modname] | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| @@ -79,7 +80,7 @@ local function requireWrapper(env) | |||||||
|   local function pathSearcher(modname) |   local function pathSearcher(modname) | ||||||
|     local fname = modname:gsub('%.', '/') .. '.lua' |     local fname = modname:gsub('%.', '/') .. '.lua' | ||||||
|  |  | ||||||
|     for dir in string.gmatch(package.path, "[^:]+") do |     for dir in string.gmatch(env.package.path, "[^:]+") do | ||||||
|       local path = fs.combine(dir, fname) |       local path = fs.combine(dir, fname) | ||||||
|       if fs.exists(path) and not fs.isDir(path) then |       if fs.exists(path) and not fs.isDir(path) then | ||||||
|         return loadfile(path, env) |         return loadfile(path, env) | ||||||
| @@ -115,7 +116,7 @@ local function requireWrapper(env) | |||||||
|     local fname = modname:gsub('%.', '/') .. '.lua' |     local fname = modname:gsub('%.', '/') .. '.lua' | ||||||
|  |  | ||||||
|     if fname:sub(1, 1) ~= '/' then |     if fname:sub(1, 1) ~= '/' then | ||||||
|       for entry in string.gmatch(package.upath, "[^;]+") do |       for entry in string.gmatch(env.package.upath, "[^;]+") do | ||||||
|         local url = entry .. '/' .. fname |         local url = entry .. '/' .. fname | ||||||
|         local c = loadUrl(url) |         local c = loadUrl(url) | ||||||
|         if c then |         if c then | ||||||
| @@ -127,8 +128,8 @@ local function requireWrapper(env) | |||||||
|  |  | ||||||
|   -- place package and require function into env |   -- place package and require function into env | ||||||
|   env.package = { |   env.package = { | ||||||
|     path = LUA_PATH or 'sys/apis', |     path = env.LUA_PATH or 'sys/apis', | ||||||
|     upath = LUA_UPATH or DEFAULT_UPATH, |     upath = env.LUA_UPATH or DEFAULT_UPATH, | ||||||
|     config = '/\n:\n?\n!\n-', |     config = '/\n:\n?\n!\n-', | ||||||
|     loaded = { |     loaded = { | ||||||
|       math   = math, |       math   = math, | ||||||
| @@ -148,15 +149,14 @@ local function requireWrapper(env) | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   function env.require(modname) |   function env.require(modname) | ||||||
|  |     for _,searcher in ipairs(env.package.loaders) do | ||||||
|     for _,searcher in ipairs(package.loaders) do |  | ||||||
|       local fn, msg = searcher(modname) |       local fn, msg = searcher(modname) | ||||||
|       if fn then |       if fn then | ||||||
|         local module, msg2 = fn(modname, env) |         local module, msg2 = fn(modname, env) | ||||||
|         if not module then |         if not module then | ||||||
|           error(msg2 or (modname .. ' module returned nil'), 2) |           error(msg2 or (modname .. ' module returned nil'), 2) | ||||||
|         end |         end | ||||||
|         package.loaded[modname] = module |         env.package.loaded[modname] = module | ||||||
|         return module |         return module | ||||||
|       end |       end | ||||||
|       if msg then |       if msg then | ||||||
| @@ -171,6 +171,6 @@ end | |||||||
|  |  | ||||||
| return function(env) | return function(env) | ||||||
|   env = env or getfenv(2) |   env = env or getfenv(2) | ||||||
|   setfenv(requireWrapper, env) |   --setfenv(requireWrapper, env) | ||||||
|   return requireWrapper(env) |   return requireWrapper(env) | ||||||
| end | end | ||||||
|   | |||||||
| @@ -121,10 +121,10 @@ function Peripheral.get(args) | |||||||
| end | end | ||||||
|  |  | ||||||
| local function getProxy(pi) | local function getProxy(pi) | ||||||
|   local socket = Socket.connect(pi.host, 189) |   local socket, msg = Socket.connect(pi.host, 189) | ||||||
|  |  | ||||||
|   if not socket then |   if not socket then | ||||||
|     error("Timed out attaching peripheral: " .. pi.uri) |     error("Timed out attaching peripheral: " .. pi.uri .. '\n' .. msg) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   -- write the uri of the periperal we are requesting... |   -- write the uri of the periperal we are requesting... | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ function socketClass:read(timeout) | |||||||
|   while true do |   while true do | ||||||
|     local e, id = os.pullEvent() |     local e, id = os.pullEvent() | ||||||
|  |  | ||||||
|     if e == 'transport_' .. self.sport then |     if e == 'transport_' .. self.uid then | ||||||
|       data, distance = _G.transport.read(self) |       data, distance = _G.transport.read(self) | ||||||
|       if data then |       if data then | ||||||
|         os.cancelTimer(timerId) |         os.cancelTimer(timerId) | ||||||
|   | |||||||
| @@ -1,38 +1,227 @@ | |||||||
| local colors = _G.colors | local colors = _G.colors | ||||||
| local term   = _G.term | local term   = _G.term | ||||||
| local _gsub  = string.gsub | local _gsub  = string.gsub | ||||||
|  | local _rep = string.rep | ||||||
|  | local _sub = string.sub | ||||||
|  |  | ||||||
| local Terminal = { } | local Terminal = { } | ||||||
|  |  | ||||||
| function Terminal.scrollable(win, parent) | -- add scrolling functions to a window | ||||||
|   local w, h = win.getSize() | function Terminal.scrollable(win, maxScroll) | ||||||
|   local _, ph = parent.getSize() |   local lines = { } | ||||||
|   local scrollPos = 0 |   local scrollPos = 0 | ||||||
|   local scp = win.setCursorPos |   local oblit, oreposition = win.blit, win.reposition | ||||||
|  |  | ||||||
|   win.setCursorPos = function(x, y) |   local palette = { } | ||||||
|   _G._p = y |   for n = 1, 16 do | ||||||
|     if y > scrollPos + ph then |     palette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n) | ||||||
|       win.scrollTo(y - ph) |   end | ||||||
|  |  | ||||||
|  |   maxScroll = maxScroll or 100 | ||||||
|  |  | ||||||
|  |   -- should only do if window is visible... | ||||||
|  |   local function redraw() | ||||||
|  |     local _, h = win.getSize() | ||||||
|  |     local x, y = win.getCursorPos() | ||||||
|  |     for i = 1, h do | ||||||
|  |       local line = lines[i + scrollPos] | ||||||
|  |       if line and line.dirty then | ||||||
|  |         win.setCursorPos(1, i) | ||||||
|  |         oblit(line.text, line.fg, line.bg) | ||||||
|  |         line.dirty = false | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|     scp(x, y) |     win.setCursorPos(x, y) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   win.scrollUp = function() |   local function scrollTo(p, forceRedraw) | ||||||
|     win.scrollTo(scrollPos - 1) |     local _, h = win.getSize() | ||||||
|   end |     local ms = #lines - h            -- max scroll | ||||||
|  |     p = math.min(math.max(p, 0), ms) -- normalize | ||||||
|  |  | ||||||
|   win.scrollDown = function() |     if p ~= scrollPos or forceRedraw then | ||||||
|     win.scrollTo(scrollPos + 1) |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   win.scrollTo = function(p) |  | ||||||
|     p = math.min(math.max(p, 0), h - ph) |  | ||||||
|     if p ~= scrollPos then |  | ||||||
|       scrollPos = p |       scrollPos = p | ||||||
|       win.reposition(1, -scrollPos + 1, w, h) |       for _, line in pairs(lines) do | ||||||
|  |         line.dirty = true | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   function win.write(text) | ||||||
|  |     local _, h = win.getSize() | ||||||
|  |  | ||||||
|  |     scrollTo(#lines - h) | ||||||
|  |     win.blit(tostring(text), | ||||||
|  |       _rep(palette[win.getTextColor()], #text), | ||||||
|  |       _rep(palette[win.getBackgroundColor()], #text)) | ||||||
|  |     local x, y = win.getCursorPos() | ||||||
|  |     win.setCursorPos(x + #text, y) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.clearLine() | ||||||
|  |     local w, h = win.getSize() | ||||||
|  |     local _, y = win.getCursorPos() | ||||||
|  |  | ||||||
|  |     scrollTo(#lines - h) | ||||||
|  |     lines[y + scrollPos] = { | ||||||
|  |       text = _rep(' ', w), | ||||||
|  |       fg = _rep(palette[win.getTextColor()], w), | ||||||
|  |       bg = _rep(palette[win.getBackgroundColor()], w), | ||||||
|  |       dirty = true, | ||||||
|  |     } | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.blit(text, fg, bg) | ||||||
|  |     local x, y = win.getCursorPos() | ||||||
|  |     local w, h = win.getSize() | ||||||
|  |  | ||||||
|  |     if y > 0 and y <= h and x <= w then | ||||||
|  |       local width = #text | ||||||
|  |  | ||||||
|  |       -- fix ffs | ||||||
|  |       if x < 1 then | ||||||
|  |         text = _sub(text, 2 - x) | ||||||
|  |         if bg then | ||||||
|  |           bg = _sub(bg, 2 - x) | ||||||
|  |         end | ||||||
|  |         if bg then | ||||||
|  |           fg = _sub(fg, 2 - x) | ||||||
|  |         end | ||||||
|  |         width = width + x - 1 | ||||||
|  |         x = 1 | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if x + width - 1 > w then | ||||||
|  |         text = _sub(text, 1, w - x + 1) | ||||||
|  |         if bg then | ||||||
|  |           bg = _sub(bg, 1, w - x + 1) | ||||||
|  |         end | ||||||
|  |         if bg then | ||||||
|  |           fg = _sub(fg, 1, w - x + 1) | ||||||
|  |         end | ||||||
|  |         width = #text | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if width > 0 then | ||||||
|  |         local function replace(sstr, pos, rstr) | ||||||
|  |           if pos == 1 and width == w then | ||||||
|  |             return rstr | ||||||
|  |           elseif pos == 1 then | ||||||
|  |             return rstr .. _sub(sstr, pos+width) | ||||||
|  |           elseif pos + width > w then | ||||||
|  |             return _sub(sstr, 1, pos-1) .. rstr | ||||||
|  |           end | ||||||
|  |           return _sub(sstr, 1, pos-1) .. rstr .. _sub(sstr, pos+width) | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         local line = lines[y + scrollPos] | ||||||
|  |         line.dirty = true | ||||||
|  |         line.text = replace(line.text, x, text, width) | ||||||
|  |         if fg then | ||||||
|  |           line.fg = replace(line.fg, x, fg, width) | ||||||
|  |         end | ||||||
|  |         if bg then | ||||||
|  |           line.bg = replace(line.bg, x, bg, width) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.clear() | ||||||
|  |     local w, h = win.getSize() | ||||||
|  |  | ||||||
|  |     local text = _rep(' ', w) | ||||||
|  |     local fg = _rep(palette[win.getTextColor()], w) | ||||||
|  |     local bg = _rep(palette[win.getBackgroundColor()], w) | ||||||
|  |     lines = { } | ||||||
|  |     for y = 1, h do | ||||||
|  |       lines[y] = { | ||||||
|  |         dirty = true, | ||||||
|  |         text = text, | ||||||
|  |         fg = fg, | ||||||
|  |         bg = bg, | ||||||
|  |       } | ||||||
|  |     end | ||||||
|  |     scrollPos = 0 | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   -- doesn't support negative scrolling... | ||||||
|  |   function win.scroll(n) | ||||||
|  |     local w = win.getSize() | ||||||
|  |  | ||||||
|  |     for _ = 1, n do | ||||||
|  |       lines[#lines + 1] = { | ||||||
|  |         text = _rep(' ', w), | ||||||
|  |         fg = _rep(palette[win.getTextColor()], w), | ||||||
|  |         bg = _rep(palette[win.getBackgroundColor()], w), | ||||||
|  |       } | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     while #lines > maxScroll do | ||||||
|  |       table.remove(lines, 1) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     scrollTo(maxScroll, true) | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.scrollUp() | ||||||
|  |     scrollTo(scrollPos - 1) | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.scrollDown() | ||||||
|  |     scrollTo(scrollPos + 1) | ||||||
|  |     redraw() | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   function win.reposition(x, y, nw, nh) | ||||||
|  |     local w, h = win.getSize() | ||||||
|  |     local D = (nh or h) - h | ||||||
|  |  | ||||||
|  |     if D > 0 then | ||||||
|  |       for _ = 1, D do | ||||||
|  |         lines[#lines + 1] = { | ||||||
|  |           text = _rep(' ', w), | ||||||
|  |           fg = _rep(palette[win.getTextColor()], w), | ||||||
|  |           bg = _rep(palette[win.getBackgroundColor()], w), | ||||||
|  |         } | ||||||
|  |       end | ||||||
|  |     elseif D < 0 then | ||||||
|  |       for _ = D, -1 do | ||||||
|  |         lines[#lines] = nil | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     return oreposition(x, y, nw, nh) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   win.clear() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | -- get windows contents | ||||||
|  | function Terminal.getContents(win, parent) | ||||||
|  |   local oblit, oscp = parent.blit, parent.setCursorPos | ||||||
|  |   local lines = { } | ||||||
|  |  | ||||||
|  |   parent.blit = function(text, fg, bg) | ||||||
|  |     lines[#lines + 1] = { | ||||||
|  |       text = text, | ||||||
|  |       fg = fg, | ||||||
|  |       bg = bg, | ||||||
|  |     } | ||||||
|  |   end | ||||||
|  |   parent.setCursorPos = function() end | ||||||
|  |  | ||||||
|  |   win.setVisible(true) | ||||||
|  |   win.redraw() | ||||||
|  |  | ||||||
|  |   parent.blit = oblit | ||||||
|  |   parent.setCursorPos = oscp | ||||||
|  |  | ||||||
|  |   return lines | ||||||
| end | end | ||||||
|  |  | ||||||
| function Terminal.toGrayscale(ct) | function Terminal.toGrayscale(ct) | ||||||
|   | |||||||
| @@ -154,6 +154,7 @@ function Util.merge(obj, args) | |||||||
|       obj[k] = v |       obj[k] = v | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |   return obj | ||||||
| end | end | ||||||
|  |  | ||||||
| function Util.deepMerge(obj, args) | function Util.deepMerge(obj, args) | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ local multishell = _ENV.multishell | |||||||
| local os         = _G.os | local os         = _G.os | ||||||
| local shell      = _ENV.shell | local shell      = _ENV.shell | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'Files') |  | ||||||
| UI:configure('Files', ...) | UI:configure('Files', ...) | ||||||
|  |  | ||||||
| local config = { | local config = { | ||||||
| @@ -255,9 +254,15 @@ function Browser:setDir(dirName, noStatus) | |||||||
|   self.grid:setIndex(self.dir.index) |   self.grid:setIndex(self.dir.index) | ||||||
| end | end | ||||||
|  |  | ||||||
| function Browser:run(path, ...) | function Browser:run(...) | ||||||
|   local tabId = shell.openTab(path, ...) |   if multishell then | ||||||
|   multishell.setFocus(tabId) |     local tabId = shell.openTab(...) | ||||||
|  |     multishell.setFocus(tabId) | ||||||
|  |   else | ||||||
|  |     shell.run(...) | ||||||
|  |     Event.terminate = false | ||||||
|  |     self:draw() | ||||||
|  |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| function Browser:hasMarked() | function Browser:hasMarked() | ||||||
|   | |||||||
| @@ -5,9 +5,7 @@ local Util  = require('util') | |||||||
|  |  | ||||||
| local colors     = _G.colors | local colors     = _G.colors | ||||||
| local help       = _G.help | local help       = _G.help | ||||||
| local multishell = _ENV.multishell |  | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'Help') |  | ||||||
| UI:configure('Help', ...) | UI:configure('Help', ...) | ||||||
|  |  | ||||||
| local topics = { } | local topics = { } | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ local UI         = require('ui') | |||||||
| local Util       = require('util') | local Util       = require('util') | ||||||
|  |  | ||||||
| local colors     = _G.colors | local colors     = _G.colors | ||||||
| local multishell = _ENV.multishell |  | ||||||
| local os         = _G.os | local os         = _G.os | ||||||
| local textutils  = _G.textutils | local textutils  = _G.textutils | ||||||
|  |  | ||||||
| @@ -16,9 +15,6 @@ sandboxEnv.exit = function() Event.exitPullEvents() end | |||||||
| sandboxEnv._echo = function( ... ) return { ... } end | sandboxEnv._echo = function( ... ) return { ... } end | ||||||
| injector(sandboxEnv) | injector(sandboxEnv) | ||||||
|  |  | ||||||
| if multishell and multishell.setTitle then |  | ||||||
|   multishell.setTitle(multishell.getCurrent(), 'Lua') |  | ||||||
| end |  | ||||||
| UI:configure('Lua', ...) | UI:configure('Lua', ...) | ||||||
|  |  | ||||||
| local command = '' | local command = '' | ||||||
|   | |||||||
| @@ -12,7 +12,6 @@ local network    = _G.network | |||||||
| local os         = _G.os | local os         = _G.os | ||||||
| local shell      = _ENV.shell | local shell      = _ENV.shell | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'Network') |  | ||||||
| UI:configure('Network', ...) | UI:configure('Network', ...) | ||||||
|  |  | ||||||
| local gridColumns = { | local gridColumns = { | ||||||
|   | |||||||
| @@ -11,14 +11,13 @@ local UI     = require('ui') | |||||||
| local Util   = require('util') | local Util   = require('util') | ||||||
|  |  | ||||||
| local fs         = _G.fs | local fs         = _G.fs | ||||||
| local multishell = _ENV.multishell | local multishell = _ENV.multishell or error('This program requires multishell') | ||||||
| local pocket     = _G.pocket | local pocket     = _G.pocket | ||||||
| local term       = _G.term | local term       = _G.term | ||||||
| local turtle     = _G.turtle | local turtle     = _G.turtle | ||||||
|  |  | ||||||
| local REGISTRY_DIR = 'usr/.registry' | local REGISTRY_DIR = 'usr/.registry' | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'Overview') |  | ||||||
| UI:configure('Overview', ...) | UI:configure('Overview', ...) | ||||||
|  |  | ||||||
| local config = { | local config = { | ||||||
|   | |||||||
| @@ -7,13 +7,11 @@ local UI       = require('ui') | |||||||
| local Util     = require('util') | local Util     = require('util') | ||||||
|  |  | ||||||
| local fs         = _G.fs | local fs         = _G.fs | ||||||
| local multishell = _ENV.multishell |  | ||||||
| local os         = _G.os | local os         = _G.os | ||||||
| local settings   = _G.settings | local settings   = _G.settings | ||||||
| local shell      = _ENV.shell | local shell      = _ENV.shell | ||||||
| local turtle     = _G.turtle | local turtle     = _G.turtle | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'System') |  | ||||||
| UI:configure('System', ...) | UI:configure('System', ...) | ||||||
|  |  | ||||||
| local env = { | local env = { | ||||||
|   | |||||||
| @@ -4,9 +4,9 @@ local Event = require('event') | |||||||
| local UI    = require('ui') | local UI    = require('ui') | ||||||
| local Util  = require('util') | local Util  = require('util') | ||||||
| 
 | 
 | ||||||
|  | local kernel     = _G.kernel | ||||||
| local multishell = _ENV.multishell | local multishell = _ENV.multishell | ||||||
| 
 | 
 | ||||||
| multishell.setTitle(multishell.getCurrent(), 'Tasks') |  | ||||||
| UI:configure('Tasks', ...) | UI:configure('Tasks', ...) | ||||||
| 
 | 
 | ||||||
| local page = UI.Page { | local page = UI.Page { | ||||||
| @@ -24,7 +24,7 @@ local page = UI.Page { | |||||||
|       { heading = 'Status', key = 'status'    }, |       { heading = 'Status', key = 'status'    }, | ||||||
|       { heading = 'Time',   key = 'timestamp' }, |       { heading = 'Time',   key = 'timestamp' }, | ||||||
|     }, |     }, | ||||||
|     values = multishell.getTabs(), |     values = kernel.routines, | ||||||
|     sortColumn = 'uid', |     sortColumn = 'uid', | ||||||
|     autospace = true, |     autospace = true, | ||||||
|   }, |   }, | ||||||
| @@ -1,18 +1,15 @@ | |||||||
| local parentShell = _ENV.shell | local parentShell = _ENV.shell | ||||||
|  |  | ||||||
| _ENV.shell = { } | _ENV.shell = { } | ||||||
| --_ENV.multishell = _ENV.multishell or { } |  | ||||||
|  |  | ||||||
| local fs         = _G.fs | local fs         = _G.fs | ||||||
| local shell      = _ENV.shell | local shell      = _ENV.shell | ||||||
| --local multishell = _ENV.multishell |  | ||||||
|  |  | ||||||
| local sandboxEnv = setmetatable({ }, { __index = _G }) | local sandboxEnv = setmetatable({ }, { __index = _G }) | ||||||
| for k,v in pairs(_ENV) do | for k,v in pairs(_ENV) do | ||||||
|   sandboxEnv[k] = v |   sandboxEnv[k] = v | ||||||
| end | end | ||||||
| sandboxEnv.shell = shell | sandboxEnv.shell = shell | ||||||
| --sandboxEnv.multishell = multishell |  | ||||||
|  |  | ||||||
| _G.requireInjector() | _G.requireInjector() | ||||||
|  |  | ||||||
| @@ -64,7 +61,7 @@ local function run(env, ...) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   if _ENV.multishell then |   if _ENV.multishell then | ||||||
|     _ENV.multishell.setTitle(_ENV.multishell.getCurrent(), fs.getName(path)) |     _ENV.multishell.setTitle(_ENV.multishell.getCurrent(), fs.getName(path):match('([^%.]+)')) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   if isUrl then |   if isUrl then | ||||||
| @@ -309,7 +306,7 @@ function shell.newTab(tabInfo, ...) | |||||||
|     tabInfo.path = path |     tabInfo.path = path | ||||||
|     tabInfo.env = sandboxEnv |     tabInfo.env = sandboxEnv | ||||||
|     tabInfo.args = args |     tabInfo.args = args | ||||||
|     tabInfo.title = fs.getName(path) |     tabInfo.title = fs.getName(path):match('([^%.]+)') | ||||||
|  |  | ||||||
|     if path ~= 'sys/apps/shell' then |     if path ~= 'sys/apps/shell' then | ||||||
|       table.insert(tabInfo.args, 1, tabInfo.path) |       table.insert(tabInfo.args, 1, tabInfo.path) | ||||||
| @@ -345,6 +342,7 @@ end | |||||||
|  |  | ||||||
| local Config  = require('config') | local Config  = require('config') | ||||||
| local History = require('history') | local History = require('history') | ||||||
|  | local Terminal = require('terminal') | ||||||
|  |  | ||||||
| local colors    = _G.colors | local colors    = _G.colors | ||||||
| local keys      = _G.keys | local keys      = _G.keys | ||||||
| @@ -352,6 +350,10 @@ local os        = _G.os | |||||||
| local term      = _G.term | local term      = _G.term | ||||||
| local textutils = _G.textutils | local textutils = _G.textutils | ||||||
|  |  | ||||||
|  | local terminal = term.current() | ||||||
|  | Terminal.scrollable(terminal, 100) | ||||||
|  | terminal.noAutoScroll = true | ||||||
|  |  | ||||||
| local config = { | local config = { | ||||||
|   standard = { |   standard = { | ||||||
|     textColor  = colors.white, |     textColor  = colors.white, | ||||||
| @@ -567,6 +569,12 @@ local function shellRead(history) | |||||||
|       sLine = '' |       sLine = '' | ||||||
|       nPos = 0 |       nPos = 0 | ||||||
|       redraw() |       redraw() | ||||||
|  |     elseif sEvent == 'mouse_scroll' then | ||||||
|  |       if param == -1 then | ||||||
|  |         terminal.scrollUp() | ||||||
|  |       else | ||||||
|  |         terminal.scrollDown() | ||||||
|  |       end | ||||||
|     elseif sEvent == 'terminate' then |     elseif sEvent == 'terminate' then | ||||||
|       bExit = true |       bExit = true | ||||||
|       break |       break | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ if not remoteId then | |||||||
|   error('Syntax: telnet [-title TITLE] ID [PROGRAM]') |   error('Syntax: telnet [-title TITLE] ID [PROGRAM]') | ||||||
| end | end | ||||||
|  |  | ||||||
| if options.title then | if options.title and multishell then | ||||||
|   multishell.setTitle(multishell.getCurrent(), options.title) |   multishell.setTitle(multishell.getCurrent(), options.title) | ||||||
| end | end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,7 +22,9 @@ if not remoteId then | |||||||
|   error('Syntax: vnc <host ID>') |   error('Syntax: vnc <host ID>') | ||||||
| end | end | ||||||
|  |  | ||||||
| multishell.setTitle(multishell.getCurrent(), 'VNC-' .. remoteId) | if multishell then | ||||||
|  |   multishell.setTitle(multishell.getCurrent(), 'VNC-' .. remoteId) | ||||||
|  | end | ||||||
|  |  | ||||||
| print('connecting...') | print('connecting...') | ||||||
| local socket, msg = Socket.connect(remoteId, 5900) | local socket, msg = Socket.connect(remoteId, 5900) | ||||||
|   | |||||||
| @@ -25,10 +25,7 @@ end | |||||||
| local function run(file, ...) | local function run(file, ...) | ||||||
|   local s, m = loadfile(file, makeEnv()) |   local s, m = loadfile(file, makeEnv()) | ||||||
|   if s then |   if s then | ||||||
|     s, m = pcall(s, ...) |     return s(...) | ||||||
|     if s then |  | ||||||
|       return m |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
|   error('Error loading ' .. file .. '\n' .. m) |   error('Error loading ' .. file .. '\n' .. m) | ||||||
| end | end | ||||||
| @@ -47,23 +44,19 @@ local function runUrl(file, ...) | |||||||
|   error('Failed to download ' .. url) |   error('Failed to download ' .. url) | ||||||
| end | end | ||||||
|  |  | ||||||
| local args = { ... } | -- Install require shim | ||||||
|  | if fs.exists('sys/apis/injector.lua') then | ||||||
|  |   _G.requireInjector = run('sys/apis/injector.lua') | ||||||
|  | else | ||||||
|  |   -- not local, run the file system directly from git | ||||||
|  |   _G.requireInjector = runUrl('sys/apis/injector.lua') | ||||||
|  |   runUrl('sys/extensions/2.vfs.lua') | ||||||
|  |  | ||||||
| local s, m = pcall(function() |   -- install file system | ||||||
|   -- Install require shim |   fs.mount('', 'gitfs', GIT_REPO) | ||||||
|   if fs.exists('sys/apis/injector.lua') then | end | ||||||
|     _G.requireInjector = run('sys/apis/injector.lua') |  | ||||||
|   else |  | ||||||
|     -- not local, run the file system directly from git |  | ||||||
|     _G.requireInjector = runUrl('sys/apis/injector.lua') |  | ||||||
|     runUrl('sys/extensions/2.vfs.lua') |  | ||||||
|  |  | ||||||
|     -- install file system | local s, m = pcall(run, 'sys/apps/shell', 'sys/kernel.lua', ...) | ||||||
|     fs.mount('', 'gitfs', GIT_REPO) |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   run('sys/apps/shell', 'sys/kernel.lua', table.unpack(args)) |  | ||||||
| end) |  | ||||||
|  |  | ||||||
| if not s then | if not s then | ||||||
|   print('\nError loading Opus OS\n') |   print('\nError loading Opus OS\n') | ||||||
|   | |||||||
| @@ -2,14 +2,14 @@ local pullEvent = os.pullEventRaw | |||||||
| local shutdown = os.shutdown | local shutdown = os.shutdown | ||||||
|  |  | ||||||
| os.pullEventRaw = function() | os.pullEventRaw = function() | ||||||
|   error('die') |   error('') | ||||||
| end | end | ||||||
|  |  | ||||||
| os.shutdown = function() | os.shutdown = function() | ||||||
|   os.pullEventRaw = pullEvent |   os.pullEventRaw = pullEvent | ||||||
|   os.shutdown = shutdown |   os.shutdown = shutdown | ||||||
|  |  | ||||||
|   os.run(getfenv(1), 'sys/boot/multishell.boot') |   os.run(getfenv(1), 'sys/boot/opus.boot') | ||||||
| end | end | ||||||
|  |  | ||||||
| os.queueEvent('modem_message') | os.queueEvent('modem_message') | ||||||
|   | |||||||
| @@ -95,7 +95,7 @@ | |||||||
| \030 \031f |  |\ | \030 \031f |  |\ | ||||||
| \030 \031fo| o|\ | \030 \031fo| o|\ | ||||||
| ", | ", | ||||||
|     run = "usr/apps/music.lua", |     run = "usr/apps/Music.lua", | ||||||
|     requires = 'turtle', |     requires = 'turtle', | ||||||
|   }, |   }, | ||||||
|   c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = { |   c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = { | ||||||
| @@ -128,7 +128,7 @@ | |||||||
|     icon = "\0304  \030   \ |     icon = "\0304  \030   \ | ||||||
| \030f \0304 \0307 \030 \031  \031f_\ | \030f \0304 \0307 \030 \031  \031f_\ | ||||||
| \030f \0304 \0307 \030 \031f/", | \030f \0304 \0307 \030 \031f/", | ||||||
|     run = "Peripherals.lua", |     run = "Devices.lua", | ||||||
|   }, |   }, | ||||||
|   f39d173d91c22348565c20283b89d4d1cabd3b7e = { |   f39d173d91c22348565c20283b89d4d1cabd3b7e = { | ||||||
|     title = "Falling", |     title = "Falling", | ||||||
| @@ -170,7 +170,7 @@ | |||||||
|     icon = "\030f\031f    \0315/\ |     icon = "\030f\031f    \0315/\ | ||||||
| \030f\031f \0315/\\/ \ | \030f\031f \0315/\\/ \ | ||||||
| \030f\0315/\031f    ", | \030f\0315/\031f    ", | ||||||
|     run = "Tabs.lua", |     run = "Tasks.lua", | ||||||
|   }, |   }, | ||||||
|   [ "114edfc04a1ab03541bdc80ce064f66a7cfcedbb" ] = { |   [ "114edfc04a1ab03541bdc80ce064f66a7cfcedbb" ] = { | ||||||
|     title = "Recorder", |     title = "Recorder", | ||||||
|   | |||||||
| @@ -1,44 +0,0 @@ | |||||||
| if false then |  | ||||||
|   local colors = _G.colors |  | ||||||
|   local term   = _G.term |  | ||||||
|   local window = _G.window |  | ||||||
|  |  | ||||||
|   local terminal = term.current() |  | ||||||
|   local w, h = term.getSize() |  | ||||||
|  |  | ||||||
|   local splashWindow = window.create(terminal.parent, 1, 1, w, h, false) |  | ||||||
|   splashWindow.setTextColor(colors.white) |  | ||||||
|   if splashWindow.isColor() then |  | ||||||
|     splashWindow.setBackgroundColor(colors.black) |  | ||||||
|     splashWindow.clear() |  | ||||||
|     local opus = { |  | ||||||
|       'fffff00', |  | ||||||
|       'ffff07000', |  | ||||||
|       'ff00770b00 4444', |  | ||||||
|       'ff077777444444444', |  | ||||||
|       'f07777744444444444', |  | ||||||
|       'f0000777444444444', |  | ||||||
|       '070000111744444', |  | ||||||
|       '777770000', |  | ||||||
|       '7777000000', |  | ||||||
|       '70700000000', |  | ||||||
|       '077000000000', |  | ||||||
|     } |  | ||||||
|     for k,line in ipairs(opus) do |  | ||||||
|       splashWindow.setCursorPos((w - 18) / 2, k + (h - #opus) / 2) |  | ||||||
|       splashWindow.blit(string.rep(' ', #line), string.rep('a', #line), line) |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local str = 'Loading Opus OS...' |  | ||||||
|   print(str) |  | ||||||
|   splashWindow.setCursorPos((w - #str) / 2, h) |  | ||||||
|   splashWindow.write(str) |  | ||||||
|  |  | ||||||
|   terminal.setVisible(false) |  | ||||||
|   splashWindow.setVisible(true) |  | ||||||
|  |  | ||||||
|   kernel.hook('kernel_ready', function() |  | ||||||
|     kernel.window.setVisible(true) |  | ||||||
|   end) |  | ||||||
| end |  | ||||||
| @@ -1,7 +1,7 @@ | |||||||
|  | local os = _G.os | ||||||
|  |  | ||||||
| -- Default label | -- Default label | ||||||
| if not os.getComputerLabel() then | if not os.getComputerLabel() then | ||||||
|   showStatus('Setting computer label') |  | ||||||
|  |  | ||||||
|   local id = os.getComputerID() |   local id = os.getComputerID() | ||||||
|   if _G.turtle then |   if _G.turtle then | ||||||
|     os.setComputerLabel('turtle_' .. id) |     os.setComputerLabel('turtle_' .. id) | ||||||
|   | |||||||
| @@ -11,8 +11,8 @@ end | |||||||
| if not fs.exists('usr/autorun') then | if not fs.exists('usr/autorun') then | ||||||
|   fs.makeDir('usr/autorun') |   fs.makeDir('usr/autorun') | ||||||
| end | end | ||||||
| if not fs.exists('usr/etc/fstab') then | if not fs.exists('usr/config/fstab') then | ||||||
|   Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/' .. _ENV.BRANCH) |   Util.writeFile('usr/config/fstab', 'usr gitfs kepler155c/opus-apps/' .. _ENV.BRANCH) | ||||||
| end | end | ||||||
|  |  | ||||||
| if not fs.exists('usr/config/shell') then | if not fs.exists('usr/config/shell') then | ||||||
| @@ -35,4 +35,4 @@ end | |||||||
| shell.setPath(config.path) | shell.setPath(config.path) | ||||||
| shell.setEnv('LUA_PATH', config.lua_path) | shell.setEnv('LUA_PATH', config.lua_path) | ||||||
|  |  | ||||||
| fs.loadTab('usr/etc/fstab') | fs.loadTab('usr/config/fstab') | ||||||
|   | |||||||
| @@ -21,3 +21,4 @@ if _G.device.wireless_modem then | |||||||
| 	startNetwork() | 	startNetwork() | ||||||
| 	os.sleep(0) -- give the network a cycle to start | 	os.sleep(0) -- give the network a cycle to start | ||||||
| end | end | ||||||
|  | 
 | ||||||
| @@ -54,7 +54,7 @@ local function redrawMenu() | |||||||
| end | end | ||||||
|  |  | ||||||
| function multishell.getFocus() | function multishell.getFocus() | ||||||
|   local currentTab = kernel.routines[1] |   local currentTab = kernel.getFocused() | ||||||
|   return currentTab.uid |   return currentTab.uid | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -70,9 +70,7 @@ end | |||||||
| function multishell.setTitle(tabId, title) | function multishell.setTitle(tabId, title) | ||||||
|   local tab = kernel.find(tabId) |   local tab = kernel.find(tabId) | ||||||
|   if tab then |   if tab then | ||||||
|     if not tab.isOverview then |     tab.title = title | ||||||
|       tab.title = title or '' |  | ||||||
|     end |  | ||||||
|     redrawMenu() |     redrawMenu() | ||||||
|   end |   end | ||||||
| end | end | ||||||
| @@ -105,15 +103,15 @@ end | |||||||
|  |  | ||||||
| function multishell.openTab(tab) | function multishell.openTab(tab) | ||||||
|   if not tab.title and tab.path then |   if not tab.title and tab.path then | ||||||
|     tab.title = fs.getName(tab.path) |     tab.title = fs.getName(tab.path):match('([^%.]+)') | ||||||
|   end |   end | ||||||
|   tab.title = tab.title or 'untitled' |   tab.title = tab.title or 'untitled' | ||||||
|   tab.window = window.create(parentTerm, 1, 2, w, h - 1, false) |   tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false) | ||||||
|   tab.terminal = tab.window |   tab.terminal = tab.terminal or tab.window | ||||||
|  |  | ||||||
|   local routine = kernel.newRoutine(tab) |   local routine = kernel.newRoutine(tab) | ||||||
|  |  | ||||||
|   tab.co = coroutine.create(function() |   routine.co = coroutine.create(function() | ||||||
|     local result, err |     local result, err | ||||||
|  |  | ||||||
|     if tab.fn then |     if tab.fn then | ||||||
| @@ -128,9 +126,9 @@ function multishell.openTab(tab) | |||||||
|       if err then |       if err then | ||||||
|         printError(tostring(err)) |         printError(tostring(err)) | ||||||
|       end |       end | ||||||
|       printError('Press enter to close') |       print('\nPress enter to close') | ||||||
|       tab.isDead = true |       routine.isDead = true | ||||||
|       tab.hidden = false |       routine.hidden = false | ||||||
|       while true do |       while true do | ||||||
|         local e, code = os.pullEventRaw('key') |         local e, code = os.pullEventRaw('key') | ||||||
|         if e == 'terminate' or e == 'key' and code == keys.enter then |         if e == 'terminate' or e == 'key' and code == keys.enter then | ||||||
| @@ -147,8 +145,7 @@ function multishell.openTab(tab) | |||||||
|   else |   else | ||||||
|     redrawMenu() |     redrawMenu() | ||||||
|   end |   end | ||||||
|  |   return routine.uid | ||||||
|   return tab.uid |  | ||||||
| end | end | ||||||
|  |  | ||||||
| function multishell.hideTab(tabId) | function multishell.hideTab(tabId) | ||||||
| @@ -217,10 +214,9 @@ kernel.hook('multishell_redraw', function() | |||||||
|   parentTerm.setCursorPos(1, 1) |   parentTerm.setCursorPos(1, 1) | ||||||
|   parentTerm.clearLine() |   parentTerm.clearLine() | ||||||
|  |  | ||||||
|   local currentTab = kernel.routines[1] |   local currentTab = kernel.getFocused() | ||||||
|  |  | ||||||
|   for _,tab in pairs(kernel.routines) do |   for _,tab in pairs(kernel.routines) do | ||||||
| tab.title = tab.env._APP_TITLE or tab.title |  | ||||||
|     if tab.hidden and tab ~= currentTab then |     if tab.hidden and tab ~= currentTab then | ||||||
|       tab.width = 0 |       tab.width = 0 | ||||||
|     else |     else | ||||||
| @@ -241,7 +237,8 @@ tab.title = tab.env._APP_TITLE or tab.title | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   local function compareTab(a, b) |   local function compareTab(a, b) | ||||||
|     return b.hidden and -1 or a.uid < b.uid |     if a.hidden then return false end | ||||||
|  |     return b.hidden or a.uid < b.uid | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   local tabX = 0 |   local tabX = 0 | ||||||
| @@ -295,12 +292,12 @@ end) | |||||||
|  |  | ||||||
| kernel.hook('mouse_click', function(_, eventData) | kernel.hook('mouse_click', function(_, eventData) | ||||||
|   local x, y = eventData[2], eventData[3] |   local x, y = eventData[2], eventData[3] | ||||||
|   local currentTab = kernel.routines[1] |  | ||||||
|  |  | ||||||
|   if y == 1 then |   if y == 1 then | ||||||
|     if x == 1 then |     if x == 1 then | ||||||
|       multishell.setFocus(overviewId) |       multishell.setFocus(overviewId) | ||||||
|     elseif x == w then |     elseif x == w then | ||||||
|  |       local currentTab = kernel.getFocused() | ||||||
|       if currentTab then |       if currentTab then | ||||||
|         multishell.terminate(currentTab.uid) |         multishell.terminate(currentTab.uid) | ||||||
|       end |       end | ||||||
| @@ -344,6 +341,7 @@ local function startup() | |||||||
|     for _,file in ipairs(files) do |     for _,file in ipairs(files) do | ||||||
|       os.sleep(0) |       os.sleep(0) | ||||||
|       local result, err = open(directory .. '/' .. file) |       local result, err = open(directory .. '/' .. file) | ||||||
|  |  | ||||||
|       if result then |       if result then | ||||||
|         if term.isColor() then |         if term.isColor() then | ||||||
|           term.setTextColor(colors.green) |           term.setTextColor(colors.green) | ||||||
| @@ -362,6 +360,7 @@ local function startup() | |||||||
|         if err then |         if err then | ||||||
|           _G.printError('\n' .. err) |           _G.printError('\n' .. err) | ||||||
|         end |         end | ||||||
|  |         print() | ||||||
|         success = false |         success = false | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| @@ -383,8 +382,8 @@ kernel.hook('kernel_ready', function() | |||||||
|     path = 'sys/apps/Overview.lua', |     path = 'sys/apps/Overview.lua', | ||||||
|     isOverview = true, |     isOverview = true, | ||||||
|     focused = true, |     focused = true, | ||||||
|  |     title = '+', | ||||||
|   }) |   }) | ||||||
|   kernel.find(overviewId).title = '+' |  | ||||||
|  |  | ||||||
|   multishell.openTab({ |   multishell.openTab({ | ||||||
|     fn = startup, |     fn = startup, | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| _G.requireInjector() | _G.requireInjector() | ||||||
|  |  | ||||||
| local Util = require('util') | local Terminal = require('terminal') | ||||||
|  | local Util     = require('util') | ||||||
|  |  | ||||||
| _G.kernel = { | _G.kernel = { | ||||||
|   UID = 0, |   UID = 0, | ||||||
| @@ -19,6 +20,8 @@ local w, h = term.getSize() | |||||||
| kernel.terminal = term.current() | kernel.terminal = term.current() | ||||||
| kernel.window = window.create(kernel.terminal, 1, 1, w, h, false) | kernel.window = window.create(kernel.terminal, 1, 1, w, h, false) | ||||||
|  |  | ||||||
|  | Terminal.scrollable(kernel.window) | ||||||
|  |  | ||||||
| local focusedRoutineEvents = Util.transpose { | local focusedRoutineEvents = Util.transpose { | ||||||
|   'char', 'key', 'key_up', |   'char', 'key', 'key_up', | ||||||
|   'mouse_click', 'mouse_drag', 'mouse_scroll', 'mouse_up', |   'mouse_click', 'mouse_drag', 'mouse_scroll', 'mouse_up', | ||||||
| @@ -73,16 +76,17 @@ function Routine:resume(event, ...) | |||||||
|     local ok, result = coroutine.resume(self.co, event, ...) |     local ok, result = coroutine.resume(self.co, event, ...) | ||||||
|     kernel.running = previous |     kernel.running = previous | ||||||
|  |  | ||||||
|     self.terminal = term.current() |  | ||||||
|     term.redirect(previousTerm) |  | ||||||
|  |  | ||||||
|     if ok then |     if ok then | ||||||
|       self.filter = result |       self.filter = result | ||||||
|     else |     else | ||||||
|       _G.printError(result) |       _G.printError(result) | ||||||
|       if self.haltOnError then |     end | ||||||
|         error(result) |  | ||||||
|       end |     self.terminal = term.current() | ||||||
|  |     term.redirect(previousTerm) | ||||||
|  |  | ||||||
|  |     if not ok and self.haltOnError then | ||||||
|  |       error(result) | ||||||
|     end |     end | ||||||
|     if coroutine.status(self.co) == 'dead' then |     if coroutine.status(self.co) == 'dead' then | ||||||
|       Util.removeByValue(kernel.routines, self) |       Util.removeByValue(kernel.routines, self) | ||||||
| @@ -108,14 +112,15 @@ end | |||||||
| function kernel.newRoutine(args) | function kernel.newRoutine(args) | ||||||
|   kernel.UID = kernel.UID + 1 |   kernel.UID = kernel.UID + 1 | ||||||
|  |  | ||||||
|   args = args or { } |   local routine = setmetatable({ | ||||||
|  |     uid = kernel.UID, | ||||||
|  |     timestamp = os.clock(), | ||||||
|  |     terminal = kernel.window, | ||||||
|  |     window = kernel.window, | ||||||
|  |   }, { __index = Routine }) | ||||||
|  |  | ||||||
|   local routine = setmetatable(args, { __index = Routine }) |   Util.merge(routine, args) | ||||||
|   routine.uid = kernel.UID |  | ||||||
|   routine.timestamp = os.clock() |  | ||||||
|   routine.env = args.env or Util.shallowCopy(shell.getEnv()) |   routine.env = args.env or Util.shallowCopy(shell.getEnv()) | ||||||
|   routine.terminal = args.terminal or kernel.window |  | ||||||
|   routine.window = args.window or kernel.window |  | ||||||
|  |  | ||||||
|   return routine |   return routine | ||||||
| end | end | ||||||
| @@ -242,6 +247,7 @@ local function init(...) | |||||||
|  |  | ||||||
|   local runLevel = #args > 0 and 6 or 7 |   local runLevel = #args > 0 and 6 or 7 | ||||||
|  |  | ||||||
|  |   print('Starting Opus OS') | ||||||
|   local dir = 'sys/extensions' |   local dir = 'sys/extensions' | ||||||
|   local files = fs.list(dir) |   local files = fs.list(dir) | ||||||
|   table.sort(files) |   table.sort(files) | ||||||
| @@ -252,6 +258,7 @@ local function init(...) | |||||||
|       if not s then |       if not s then | ||||||
|         error(m) |         error(m) | ||||||
|       end |       end | ||||||
|  |       os.sleep(0) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
| @@ -264,6 +271,7 @@ local function init(...) | |||||||
|         path = 'sys/apps/shell', |         path = 'sys/apps/shell', | ||||||
|         args = args, |         args = args, | ||||||
|         haltOnExit = true, |         haltOnExit = true, | ||||||
|  |         haltOnError = true, | ||||||
|         terminal = kernel.terminal, |         terminal = kernel.terminal, | ||||||
|       }) |       }) | ||||||
|       if s then |       if s then | ||||||
|   | |||||||
| @@ -13,12 +13,16 @@ local computerId = os.getComputerID() | |||||||
| local transport = { | local transport = { | ||||||
|   timers  = { }, |   timers  = { }, | ||||||
|   sockets = { }, |   sockets = { }, | ||||||
|  |   UID = 0, | ||||||
| } | } | ||||||
| _G.transport = transport | _G.transport = transport | ||||||
|  |  | ||||||
| function transport.open(socket) | function transport.open(socket) | ||||||
|  |   transport.UID = transport.UID + 1 | ||||||
|  |  | ||||||
|   transport.sockets[socket.sport] = socket |   transport.sockets[socket.sport] = socket | ||||||
|   socket.activityTimer = os.clock() |   socket.activityTimer = os.clock() | ||||||
|  |   socket.uid = transport.UID | ||||||
| end | end | ||||||
|  |  | ||||||
| function transport.read(socket) | function transport.read(socket) | ||||||
| @@ -78,9 +82,11 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) | |||||||
|  |  | ||||||
|       if msg.type == 'DISC' then |       if msg.type == 'DISC' then | ||||||
|         -- received disconnect from other end |         -- received disconnect from other end | ||||||
|  |         if socket.connected then | ||||||
|  |           os.queueEvent('transport_' .. socket.uid) | ||||||
|  |         end | ||||||
|         socket.connected = false |         socket.connected = false | ||||||
|         socket:close() |         socket:close() | ||||||
|         os.queueEvent('transport_' .. socket.sport) |  | ||||||
|  |  | ||||||
|       elseif msg.type == 'ACK' then |       elseif msg.type == 'ACK' then | ||||||
|         local ackTimerId = socket.timers[msg.seq] |         local ackTimerId = socket.timers[msg.seq] | ||||||
| @@ -109,7 +115,7 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) | |||||||
|  |  | ||||||
|           -- use resume instead ?? |           -- use resume instead ?? | ||||||
|           if not socket.messages[2] then  -- table size is 1 |           if not socket.messages[2] then  -- table size is 1 | ||||||
|             os.queueEvent('transport_' .. socket.sport) |             os.queueEvent('transport_' .. socket.uid) | ||||||
|           end |           end | ||||||
|  |  | ||||||
|           --debug('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) |           --debug('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) | ||||||
|   | |||||||
| @@ -1,67 +1,26 @@ | |||||||
| _G.requireInjector() | _G.requireInjector(_ENV) | ||||||
|  |  | ||||||
| --[[ | --[[ | ||||||
|   Adds the control-d hotkey to view the kernel log. |   Adds a task and the control-d hotkey to view the kernel log. | ||||||
| ]] | --]] | ||||||
|  |  | ||||||
| local Terminal = require('terminal') |  | ||||||
|  |  | ||||||
| local kernel     = _G.kernel | local kernel     = _G.kernel | ||||||
| local keyboard   = _G.device.keyboard | local keyboard   = _G.device.keyboard | ||||||
| local multishell = _ENV.multishell | local multishell = _ENV.multishell | ||||||
| local os         = _G.os | local os         = _G.os | ||||||
| local term       = _G.term | local term       = _G.term | ||||||
| local window     = _G.window |  | ||||||
|  |  | ||||||
| if multishell and multishell.setTitle then | if multishell then | ||||||
|   multishell.setTitle(multishell.getCurrent(), 'System Log') |   multishell.setTitle(multishell.getCurrent(), 'System Log') | ||||||
| end | end | ||||||
|  |  | ||||||
| -- jump through a lot of hoops to get around window api limitations |  | ||||||
| -- mainly failing to provide access to window buffer or knowledge of parent |  | ||||||
| -- need: window.getParent() |  | ||||||
| --       window.copy(target) |  | ||||||
|  |  | ||||||
| local terminal = _G.kernel.terminal |  | ||||||
| local w, h = kernel.window.getSize() | local w, h = kernel.window.getSize() | ||||||
| local win = window.create(kernel.window, 1, 1, w, h + 50, false) |  | ||||||
|  |  | ||||||
| -- copy windows contents from parent window to child |  | ||||||
| local oblit, oscp = terminal.blit, terminal.setCursorPos |  | ||||||
| kernel.window.setVisible(false) |  | ||||||
| terminal.blit = function(...) |  | ||||||
|   win.blit(...) |  | ||||||
| end |  | ||||||
| terminal.setCursorPos = function(...) |  | ||||||
|   win.setCursorPos(...) |  | ||||||
| end |  | ||||||
| kernel.window.setVisible(true) |  | ||||||
|  |  | ||||||
| -- position and resize window for multishell (but don't update screen) |  | ||||||
| terminal.blit = function() end |  | ||||||
| terminal.setCursorPos = function() end |  | ||||||
| kernel.window.reposition(1, 2, w, h - 1) | kernel.window.reposition(1, 2, w, h - 1) | ||||||
|  |  | ||||||
| -- restore original terminal |  | ||||||
| terminal.blit = oblit |  | ||||||
| terminal.setCursorPos = oscp |  | ||||||
|  |  | ||||||
| -- add scrolling methods |  | ||||||
| Terminal.scrollable(win, kernel.window) |  | ||||||
|  |  | ||||||
| -- update kernel with new window, set this tab with the new kernal window |  | ||||||
| local routine = kernel.getCurrent() | local routine = kernel.getCurrent() | ||||||
| for _,r in pairs(kernel.routines) do | routine.terminal = kernel.window | ||||||
|   if r.terminal == kernel.window then | routine.window = kernel.window | ||||||
|     r.terminal = win | term.redirect(kernel.window) | ||||||
|     r.window = win |  | ||||||
|   end |  | ||||||
| end |  | ||||||
| --kernel.terminal = win |  | ||||||
| kernel.window = win |  | ||||||
| routine.terminal = win |  | ||||||
| routine.window = win |  | ||||||
| term.redirect(routine.window) |  | ||||||
|  |  | ||||||
| local previousId | local previousId | ||||||
|  |  | ||||||
| @@ -69,8 +28,8 @@ kernel.hook('mouse_scroll', function(_, eventData) | |||||||
|   local dir, y = eventData[1], eventData[3] |   local dir, y = eventData[1], eventData[3] | ||||||
|  |  | ||||||
|   if y > 1 then |   if y > 1 then | ||||||
|     local currentTab = kernel.routines[1] |     local currentTab = kernel.getFocused() | ||||||
|     if currentTab.terminal.scrollUp then |     if currentTab.terminal.scrollUp and not currentTab.terminal.noAutoScroll then | ||||||
|       if dir == -1 then |       if dir == -1 then | ||||||
|         currentTab.terminal.scrollUp() |         currentTab.terminal.scrollUp() | ||||||
|       else |       else | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 kepler155c@gmail.com
					kepler155c@gmail.com