diff --git a/startup b/startup index abc153a..0c29997 100644 --- a/startup +++ b/startup @@ -1,9 +1,18 @@ +local colors = _G.colors +local os = _G.os +local settings = _G.settings +local term = _G.term + local bootOptions = { - { prompt = 'Default Shell', file = '/sys/boot/default.boot' }, - { prompt = 'Opus' , file = '/sys/boot/opus.boot' }, --- { prompt = 'TLCO' , file = '/sys/boot/tlco.boot' }, + { prompt = os.version() }, + { prompt = 'Opus' , args = { '/sys/boot/opus.boot' } }, + { prompt = 'Opus Shell' , args = { '/sys/boot/opus.boot', 'sys/apps/shell' } }, } local bootOption = 2 +if settings then + settings.load('.settings') + bootOption = tonumber(settings.get('opus.boot_option') or 2) or 2 +end local function startupMenu() while true do @@ -16,20 +25,51 @@ local function startupMenu() end print('') term.write('> ') - local ch = tonumber(read()) + local ch = tonumber(_G.read()) if ch and bootOptions[ch] then return ch end end - term.clear() - term.setCursorPos(1, 1) +end + +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 term.clear() -term.setCursorPos(1, 1) -print('Starting OS') -print() -print('Press any key for menu') +splash() + local timerId = os.startTimer(1.5) while true do local e, id = os.pullEvent() @@ -38,8 +78,18 @@ while true do end if e == 'char' then bootOption = startupMenu() + if settings then + settings.set('opus.boot_option', bootOption) + settings.save('.settings') + end break end end -os.run(getfenv(1), bootOptions[bootOption].file) \ No newline at end of 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 diff --git a/sys/apis/event.lua b/sys/apis/event.lua index d177bae..2bfac8e 100644 --- a/sys/apis/event.lua +++ b/sys/apis/event.lua @@ -154,8 +154,10 @@ function Event.pullEvents(...) end repeat - local e = Event.pullEvent() - until e[1] == 'terminate' + Event.pullEvent() + until Event.terminate + + Event.terminate = false end function Event.exitPullEvents() @@ -203,11 +205,12 @@ function Event.pullEvent(eventType) while true do local e = { os.pullEventRaw() } + Event.terminate = Event.terminate or e[1] == 'terminate' + processHandlers(e[1]) processRoutines(table.unpack(e)) - if Event.terminate or e[1] == 'terminate' then - Event.terminate = false + if Event.terminate then return { 'terminate' } end diff --git a/sys/apis/injector.lua b/sys/apis/injector.lua index 95df150..e944775 100644 --- a/sys/apis/injector.lua +++ b/sys/apis/injector.lua @@ -55,12 +55,13 @@ local function loadUrl(url) end end +-- Add require and package to the environment local function requireWrapper(env) local function standardSearcher(modname) - if package.loaded[modname] then + if env.package.loaded[modname] then return function() - return package.loaded[modname] + return env.package.loaded[modname] end end end @@ -79,7 +80,7 @@ local function requireWrapper(env) local function pathSearcher(modname) 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) if fs.exists(path) and not fs.isDir(path) then return loadfile(path, env) @@ -115,7 +116,7 @@ local function requireWrapper(env) local fname = modname:gsub('%.', '/') .. '.lua' 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 c = loadUrl(url) if c then @@ -127,8 +128,8 @@ local function requireWrapper(env) -- place package and require function into env env.package = { - path = LUA_PATH or 'sys/apis', - upath = LUA_UPATH or DEFAULT_UPATH, + path = env.LUA_PATH or 'sys/apis', + upath = env.LUA_UPATH or DEFAULT_UPATH, config = '/\n:\n?\n!\n-', loaded = { math = math, @@ -148,15 +149,14 @@ local function requireWrapper(env) } function env.require(modname) - - for _,searcher in ipairs(package.loaders) do + for _,searcher in ipairs(env.package.loaders) do local fn, msg = searcher(modname) if fn then local module, msg2 = fn(modname, env) if not module then error(msg2 or (modname .. ' module returned nil'), 2) end - package.loaded[modname] = module + env.package.loaded[modname] = module return module end if msg then @@ -171,6 +171,6 @@ end return function(env) env = env or getfenv(2) - setfenv(requireWrapper, env) + --setfenv(requireWrapper, env) return requireWrapper(env) end diff --git a/sys/apis/peripheral.lua b/sys/apis/peripheral.lua index 022d2bf..0f7e2da 100644 --- a/sys/apis/peripheral.lua +++ b/sys/apis/peripheral.lua @@ -121,10 +121,10 @@ function Peripheral.get(args) end local function getProxy(pi) - local socket = Socket.connect(pi.host, 189) + local socket, msg = Socket.connect(pi.host, 189) if not socket then - error("Timed out attaching peripheral: " .. pi.uri) + error("Timed out attaching peripheral: " .. pi.uri .. '\n' .. msg) end -- write the uri of the periperal we are requesting... diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index a3f3e95..9c0c0d1 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -24,7 +24,7 @@ function socketClass:read(timeout) while true do local e, id = os.pullEvent() - if e == 'transport_' .. self.sport then + if e == 'transport_' .. self.uid then data, distance = _G.transport.read(self) if data then os.cancelTimer(timerId) diff --git a/sys/apis/terminal.lua b/sys/apis/terminal.lua index 9e5db8b..507eda3 100644 --- a/sys/apis/terminal.lua +++ b/sys/apis/terminal.lua @@ -1,38 +1,227 @@ local colors = _G.colors local term = _G.term local _gsub = string.gsub +local _rep = string.rep +local _sub = string.sub local Terminal = { } -function Terminal.scrollable(win, parent) - local w, h = win.getSize() - local _, ph = parent.getSize() +-- add scrolling functions to a window +function Terminal.scrollable(win, maxScroll) + local lines = { } local scrollPos = 0 - local scp = win.setCursorPos + local oblit, oreposition = win.blit, win.reposition - win.setCursorPos = function(x, y) - _G._p = y - if y > scrollPos + ph then - win.scrollTo(y - ph) + local palette = { } + for n = 1, 16 do + palette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n) + 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 - scp(x, y) + win.setCursorPos(x, y) end - win.scrollUp = function() - win.scrollTo(scrollPos - 1) - end + local function scrollTo(p, forceRedraw) + local _, h = win.getSize() + local ms = #lines - h -- max scroll + p = math.min(math.max(p, 0), ms) -- normalize - win.scrollDown = function() - win.scrollTo(scrollPos + 1) - end - - win.scrollTo = function(p) - p = math.min(math.max(p, 0), h - ph) - if p ~= scrollPos then + if p ~= scrollPos or forceRedraw then scrollPos = p - win.reposition(1, -scrollPos + 1, w, h) + for _, line in pairs(lines) do + line.dirty = true + 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 function Terminal.toGrayscale(ct) diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 76ded6e..6dc6bce 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -154,6 +154,7 @@ function Util.merge(obj, args) obj[k] = v end end + return obj end function Util.deepMerge(obj, args) diff --git a/sys/apps/Files.lua b/sys/apps/Files.lua index 114f441..53045b6 100644 --- a/sys/apps/Files.lua +++ b/sys/apps/Files.lua @@ -11,7 +11,6 @@ local multishell = _ENV.multishell local os = _G.os local shell = _ENV.shell -multishell.setTitle(multishell.getCurrent(), 'Files') UI:configure('Files', ...) local config = { @@ -255,9 +254,15 @@ function Browser:setDir(dirName, noStatus) self.grid:setIndex(self.dir.index) end -function Browser:run(path, ...) - local tabId = shell.openTab(path, ...) - multishell.setFocus(tabId) +function Browser:run(...) + if multishell then + local tabId = shell.openTab(...) + multishell.setFocus(tabId) + else + shell.run(...) + Event.terminate = false + self:draw() + end end function Browser:hasMarked() diff --git a/sys/apps/Help.lua b/sys/apps/Help.lua index abec1a8..bb2a913 100644 --- a/sys/apps/Help.lua +++ b/sys/apps/Help.lua @@ -5,9 +5,7 @@ local Util = require('util') local colors = _G.colors local help = _G.help -local multishell = _ENV.multishell -multishell.setTitle(multishell.getCurrent(), 'Help') UI:configure('Help', ...) local topics = { } diff --git a/sys/apps/Lua.lua b/sys/apps/Lua.lua index a840897..983bd16 100644 --- a/sys/apps/Lua.lua +++ b/sys/apps/Lua.lua @@ -7,7 +7,6 @@ local UI = require('ui') local Util = require('util') local colors = _G.colors -local multishell = _ENV.multishell local os = _G.os local textutils = _G.textutils @@ -16,9 +15,6 @@ sandboxEnv.exit = function() Event.exitPullEvents() end sandboxEnv._echo = function( ... ) return { ... } end injector(sandboxEnv) -if multishell and multishell.setTitle then - multishell.setTitle(multishell.getCurrent(), 'Lua') -end UI:configure('Lua', ...) local command = '' diff --git a/sys/apps/Network.lua b/sys/apps/Network.lua index c2b10b6..d8831ab 100644 --- a/sys/apps/Network.lua +++ b/sys/apps/Network.lua @@ -12,7 +12,6 @@ local network = _G.network local os = _G.os local shell = _ENV.shell -multishell.setTitle(multishell.getCurrent(), 'Network') UI:configure('Network', ...) local gridColumns = { diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index b38b273..ec22405 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -11,14 +11,13 @@ local UI = require('ui') local Util = require('util') local fs = _G.fs -local multishell = _ENV.multishell +local multishell = _ENV.multishell or error('This program requires multishell') local pocket = _G.pocket local term = _G.term local turtle = _G.turtle local REGISTRY_DIR = 'usr/.registry' -multishell.setTitle(multishell.getCurrent(), 'Overview') UI:configure('Overview', ...) local config = { diff --git a/sys/apps/System.lua b/sys/apps/System.lua index ec25b6e..078fffb 100644 --- a/sys/apps/System.lua +++ b/sys/apps/System.lua @@ -7,13 +7,11 @@ local UI = require('ui') local Util = require('util') local fs = _G.fs -local multishell = _ENV.multishell local os = _G.os local settings = _G.settings local shell = _ENV.shell local turtle = _G.turtle -multishell.setTitle(multishell.getCurrent(), 'System') UI:configure('System', ...) local env = { diff --git a/sys/apps/Tabs.lua b/sys/apps/Tasks.lua similarity index 94% rename from sys/apps/Tabs.lua rename to sys/apps/Tasks.lua index 3c6a6e4..b77b836 100644 --- a/sys/apps/Tabs.lua +++ b/sys/apps/Tasks.lua @@ -4,9 +4,9 @@ local Event = require('event') local UI = require('ui') local Util = require('util') +local kernel = _G.kernel local multishell = _ENV.multishell -multishell.setTitle(multishell.getCurrent(), 'Tasks') UI:configure('Tasks', ...) local page = UI.Page { @@ -24,7 +24,7 @@ local page = UI.Page { { heading = 'Status', key = 'status' }, { heading = 'Time', key = 'timestamp' }, }, - values = multishell.getTabs(), + values = kernel.routines, sortColumn = 'uid', autospace = true, }, diff --git a/sys/apps/shell b/sys/apps/shell index 2461f0b..41b95f1 100644 --- a/sys/apps/shell +++ b/sys/apps/shell @@ -1,18 +1,15 @@ local parentShell = _ENV.shell _ENV.shell = { } ---_ENV.multishell = _ENV.multishell or { } local fs = _G.fs local shell = _ENV.shell ---local multishell = _ENV.multishell local sandboxEnv = setmetatable({ }, { __index = _G }) for k,v in pairs(_ENV) do sandboxEnv[k] = v end sandboxEnv.shell = shell ---sandboxEnv.multishell = multishell _G.requireInjector() @@ -64,7 +61,7 @@ local function run(env, ...) end if _ENV.multishell then - _ENV.multishell.setTitle(_ENV.multishell.getCurrent(), fs.getName(path)) + _ENV.multishell.setTitle(_ENV.multishell.getCurrent(), fs.getName(path):match('([^%.]+)')) end if isUrl then @@ -309,7 +306,7 @@ function shell.newTab(tabInfo, ...) tabInfo.path = path tabInfo.env = sandboxEnv tabInfo.args = args - tabInfo.title = fs.getName(path) + tabInfo.title = fs.getName(path):match('([^%.]+)') if path ~= 'sys/apps/shell' then table.insert(tabInfo.args, 1, tabInfo.path) @@ -345,6 +342,7 @@ end local Config = require('config') local History = require('history') +local Terminal = require('terminal') local colors = _G.colors local keys = _G.keys @@ -352,6 +350,10 @@ local os = _G.os local term = _G.term local textutils = _G.textutils +local terminal = term.current() +Terminal.scrollable(terminal, 100) +terminal.noAutoScroll = true + local config = { standard = { textColor = colors.white, @@ -567,6 +569,12 @@ local function shellRead(history) sLine = '' nPos = 0 redraw() + elseif sEvent == 'mouse_scroll' then + if param == -1 then + terminal.scrollUp() + else + terminal.scrollDown() + end elseif sEvent == 'terminate' then bExit = true break diff --git a/sys/apps/telnet.lua b/sys/apps/telnet.lua index a1df07d..e77bc83 100644 --- a/sys/apps/telnet.lua +++ b/sys/apps/telnet.lua @@ -22,7 +22,7 @@ if not remoteId then error('Syntax: telnet [-title TITLE] ID [PROGRAM]') end -if options.title then +if options.title and multishell then multishell.setTitle(multishell.getCurrent(), options.title) end diff --git a/sys/apps/vnc.lua b/sys/apps/vnc.lua index df5acae..748f8f0 100644 --- a/sys/apps/vnc.lua +++ b/sys/apps/vnc.lua @@ -22,7 +22,9 @@ if not remoteId then error('Syntax: vnc ') end -multishell.setTitle(multishell.getCurrent(), 'VNC-' .. remoteId) +if multishell then + multishell.setTitle(multishell.getCurrent(), 'VNC-' .. remoteId) +end print('connecting...') local socket, msg = Socket.connect(remoteId, 5900) diff --git a/sys/boot/opus.boot b/sys/boot/opus.boot index 0df7dc5..6250651 100644 --- a/sys/boot/opus.boot +++ b/sys/boot/opus.boot @@ -25,10 +25,7 @@ end local function run(file, ...) local s, m = loadfile(file, makeEnv()) if s then - s, m = pcall(s, ...) - if s then - return m - end + return s(...) end error('Error loading ' .. file .. '\n' .. m) end @@ -47,23 +44,19 @@ local function runUrl(file, ...) error('Failed to download ' .. url) 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 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') + -- install file system + fs.mount('', 'gitfs', GIT_REPO) +end - -- install file system - fs.mount('', 'gitfs', GIT_REPO) - end - - run('sys/apps/shell', 'sys/kernel.lua', table.unpack(args)) -end) +local s, m = pcall(run, 'sys/apps/shell', 'sys/kernel.lua', ...) if not s then print('\nError loading Opus OS\n') diff --git a/sys/boot/tlco.boot b/sys/boot/tlco.boot index 9e35802..cd6d1bb 100644 --- a/sys/boot/tlco.boot +++ b/sys/boot/tlco.boot @@ -2,14 +2,14 @@ local pullEvent = os.pullEventRaw local shutdown = os.shutdown os.pullEventRaw = function() - error('die') + error('') end os.shutdown = function() os.pullEventRaw = pullEvent os.shutdown = shutdown - os.run(getfenv(1), 'sys/boot/multishell.boot') + os.run(getfenv(1), 'sys/boot/opus.boot') end os.queueEvent('modem_message') diff --git a/sys/etc/app.db b/sys/etc/app.db index 81e2a41..c1b86b2 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -95,7 +95,7 @@ \030 \031f | |\ \030 \031fo| o|\ ", - run = "usr/apps/music.lua", + run = "usr/apps/Music.lua", requires = 'turtle', }, c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = { @@ -128,7 +128,7 @@ icon = "\0304 \030 \ \030f \0304 \0307 \030 \031 \031f_\ \030f \0304 \0307 \030 \031f/", - run = "Peripherals.lua", + run = "Devices.lua", }, f39d173d91c22348565c20283b89d4d1cabd3b7e = { title = "Falling", @@ -170,7 +170,7 @@ icon = "\030f\031f \0315/\ \030f\031f \0315/\\/ \ \030f\0315/\031f ", - run = "Tabs.lua", + run = "Tasks.lua", }, [ "114edfc04a1ab03541bdc80ce064f66a7cfcedbb" ] = { title = "Recorder", diff --git a/sys/extensions/0.splash.lua b/sys/extensions/0.splash.lua deleted file mode 100644 index 2c19af0..0000000 --- a/sys/extensions/0.splash.lua +++ /dev/null @@ -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 diff --git a/sys/extensions/4.label.lua b/sys/extensions/4.label.lua index 86a079c..8878598 100644 --- a/sys/extensions/4.label.lua +++ b/sys/extensions/4.label.lua @@ -1,7 +1,7 @@ +local os = _G.os + -- Default label if not os.getComputerLabel() then - showStatus('Setting computer label') - local id = os.getComputerID() if _G.turtle then os.setComputerLabel('turtle_' .. id) diff --git a/sys/extensions/4.user.lua b/sys/extensions/4.user.lua index e922f11..5676d29 100644 --- a/sys/extensions/4.user.lua +++ b/sys/extensions/4.user.lua @@ -11,8 +11,8 @@ end if not fs.exists('usr/autorun') then fs.makeDir('usr/autorun') end -if not fs.exists('usr/etc/fstab') then - Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/' .. _ENV.BRANCH) +if not fs.exists('usr/config/fstab') then + Util.writeFile('usr/config/fstab', 'usr gitfs kepler155c/opus-apps/' .. _ENV.BRANCH) end if not fs.exists('usr/config/shell') then @@ -35,4 +35,4 @@ end shell.setPath(config.path) shell.setEnv('LUA_PATH', config.lua_path) -fs.loadTab('usr/etc/fstab') +fs.loadTab('usr/config/fstab') diff --git a/sys/extensions/3.network.lua b/sys/extensions/5.network.lua similarity index 99% rename from sys/extensions/3.network.lua rename to sys/extensions/5.network.lua index f045293..9b4b43c 100644 --- a/sys/extensions/3.network.lua +++ b/sys/extensions/5.network.lua @@ -21,3 +21,4 @@ if _G.device.wireless_modem then startNetwork() os.sleep(0) -- give the network a cycle to start end + diff --git a/sys/extensions/7.multishell.lua b/sys/extensions/7.multishell.lua index 94cd2e1..4376cc3 100644 --- a/sys/extensions/7.multishell.lua +++ b/sys/extensions/7.multishell.lua @@ -54,7 +54,7 @@ local function redrawMenu() end function multishell.getFocus() - local currentTab = kernel.routines[1] + local currentTab = kernel.getFocused() return currentTab.uid end @@ -70,9 +70,7 @@ end function multishell.setTitle(tabId, title) local tab = kernel.find(tabId) if tab then - if not tab.isOverview then - tab.title = title or '' - end + tab.title = title redrawMenu() end end @@ -105,15 +103,15 @@ end function multishell.openTab(tab) if not tab.title and tab.path then - tab.title = fs.getName(tab.path) + tab.title = fs.getName(tab.path):match('([^%.]+)') end tab.title = tab.title or 'untitled' - tab.window = window.create(parentTerm, 1, 2, w, h - 1, false) - tab.terminal = tab.window + tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false) + tab.terminal = tab.terminal or tab.window local routine = kernel.newRoutine(tab) - tab.co = coroutine.create(function() + routine.co = coroutine.create(function() local result, err if tab.fn then @@ -128,9 +126,9 @@ function multishell.openTab(tab) if err then printError(tostring(err)) end - printError('Press enter to close') - tab.isDead = true - tab.hidden = false + print('\nPress enter to close') + routine.isDead = true + routine.hidden = false while true do local e, code = os.pullEventRaw('key') if e == 'terminate' or e == 'key' and code == keys.enter then @@ -147,8 +145,7 @@ function multishell.openTab(tab) else redrawMenu() end - - return tab.uid + return routine.uid end function multishell.hideTab(tabId) @@ -217,10 +214,9 @@ kernel.hook('multishell_redraw', function() parentTerm.setCursorPos(1, 1) parentTerm.clearLine() - local currentTab = kernel.routines[1] + local currentTab = kernel.getFocused() for _,tab in pairs(kernel.routines) do -tab.title = tab.env._APP_TITLE or tab.title if tab.hidden and tab ~= currentTab then tab.width = 0 else @@ -241,7 +237,8 @@ tab.title = tab.env._APP_TITLE or tab.title end 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 local tabX = 0 @@ -295,12 +292,12 @@ end) kernel.hook('mouse_click', function(_, eventData) local x, y = eventData[2], eventData[3] - local currentTab = kernel.routines[1] if y == 1 then if x == 1 then multishell.setFocus(overviewId) elseif x == w then + local currentTab = kernel.getFocused() if currentTab then multishell.terminate(currentTab.uid) end @@ -344,6 +341,7 @@ local function startup() for _,file in ipairs(files) do os.sleep(0) local result, err = open(directory .. '/' .. file) + if result then if term.isColor() then term.setTextColor(colors.green) @@ -362,6 +360,7 @@ local function startup() if err then _G.printError('\n' .. err) end + print() success = false end end @@ -383,8 +382,8 @@ kernel.hook('kernel_ready', function() path = 'sys/apps/Overview.lua', isOverview = true, focused = true, + title = '+', }) - kernel.find(overviewId).title = '+' multishell.openTab({ fn = startup, diff --git a/sys/kernel.lua b/sys/kernel.lua index 9fcb6a4..5f519cd 100644 --- a/sys/kernel.lua +++ b/sys/kernel.lua @@ -1,6 +1,7 @@ _G.requireInjector() -local Util = require('util') +local Terminal = require('terminal') +local Util = require('util') _G.kernel = { UID = 0, @@ -19,6 +20,8 @@ local w, h = term.getSize() kernel.terminal = term.current() kernel.window = window.create(kernel.terminal, 1, 1, w, h, false) +Terminal.scrollable(kernel.window) + local focusedRoutineEvents = Util.transpose { 'char', 'key', 'key_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, ...) kernel.running = previous - self.terminal = term.current() - term.redirect(previousTerm) - if ok then self.filter = result else _G.printError(result) - if self.haltOnError then - error(result) - end + end + + self.terminal = term.current() + term.redirect(previousTerm) + + if not ok and self.haltOnError then + error(result) end if coroutine.status(self.co) == 'dead' then Util.removeByValue(kernel.routines, self) @@ -108,14 +112,15 @@ end function kernel.newRoutine(args) 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 }) - routine.uid = kernel.UID - routine.timestamp = os.clock() + Util.merge(routine, args) 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 end @@ -242,6 +247,7 @@ local function init(...) local runLevel = #args > 0 and 6 or 7 + print('Starting Opus OS') local dir = 'sys/extensions' local files = fs.list(dir) table.sort(files) @@ -252,6 +258,7 @@ local function init(...) if not s then error(m) end + os.sleep(0) end end @@ -264,6 +271,7 @@ local function init(...) path = 'sys/apps/shell', args = args, haltOnExit = true, + haltOnError = true, terminal = kernel.terminal, }) if s then diff --git a/sys/network/transport.lua b/sys/network/transport.lua index 8c290ee..fea060b 100644 --- a/sys/network/transport.lua +++ b/sys/network/transport.lua @@ -13,12 +13,16 @@ local computerId = os.getComputerID() local transport = { timers = { }, sockets = { }, + UID = 0, } _G.transport = transport function transport.open(socket) + transport.UID = transport.UID + 1 + transport.sockets[socket.sport] = socket socket.activityTimer = os.clock() + socket.uid = transport.UID end function transport.read(socket) @@ -78,9 +82,11 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) if msg.type == 'DISC' then -- received disconnect from other end + if socket.connected then + os.queueEvent('transport_' .. socket.uid) + end socket.connected = false socket:close() - os.queueEvent('transport_' .. socket.sport) elseif msg.type == 'ACK' then local ackTimerId = socket.timers[msg.seq] @@ -109,7 +115,7 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) -- use resume instead ?? if not socket.messages[2] then -- table size is 1 - os.queueEvent('transport_' .. socket.sport) + os.queueEvent('transport_' .. socket.uid) end --debug('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) diff --git a/sys/services/log.lua b/sys/services/log.lua index 35dad8a..40b24b0 100644 --- a/sys/services/log.lua +++ b/sys/services/log.lua @@ -1,67 +1,26 @@ -_G.requireInjector() +_G.requireInjector(_ENV) --[[ - Adds the control-d hotkey to view the kernel log. -]] - -local Terminal = require('terminal') + Adds a task and the control-d hotkey to view the kernel log. +--]] local kernel = _G.kernel local keyboard = _G.device.keyboard local multishell = _ENV.multishell local os = _G.os local term = _G.term -local window = _G.window -if multishell and multishell.setTitle then +if multishell then multishell.setTitle(multishell.getCurrent(), 'System Log') 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 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) --- 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() -for _,r in pairs(kernel.routines) do - if r.terminal == kernel.window then - r.terminal = win - r.window = win - end -end ---kernel.terminal = win -kernel.window = win -routine.terminal = win -routine.window = win -term.redirect(routine.window) +routine.terminal = kernel.window +routine.window = kernel.window +term.redirect(kernel.window) local previousId @@ -69,8 +28,8 @@ kernel.hook('mouse_scroll', function(_, eventData) local dir, y = eventData[1], eventData[3] if y > 1 then - local currentTab = kernel.routines[1] - if currentTab.terminal.scrollUp then + local currentTab = kernel.getFocused() + if currentTab.terminal.scrollUp and not currentTab.terminal.noAutoScroll then if dir == -1 then currentTab.terminal.scrollUp() else