1
0
mirror of https://github.com/kepler155c/opus synced 2025-10-23 11:47:39 +00:00

format and installer branches

This commit is contained in:
kepler155c@gmail.com
2018-01-24 17:39:38 -05:00
parent 1eea0d7cd8
commit 5a32fe208e
80 changed files with 10742 additions and 10156 deletions

View File

@@ -13,15 +13,15 @@ _G.device.keyboard = {
side = 'keyboard',
type = 'keyboard',
name = 'keyboard',
hotkeys = { },
state = { },
hotkeys = { },
state = { },
}
_G.device.mouse = {
side = 'mouse',
type = 'mouse',
name = 'mouse',
state = { },
state = { },
}
local Input = require('input')
@@ -34,24 +34,24 @@ local mouse = _G.device.mouse
local os = _G.os
kernel.hook('peripheral', function(_, eventData)
local side = eventData[1]
if side then
local dev = Peripheral.addDevice(device, side)
if dev then
os.queueEvent('device_attach', dev.name)
end
end
local side = eventData[1]
if side then
local dev = Peripheral.addDevice(device, side)
if dev then
os.queueEvent('device_attach', dev.name)
end
end
end)
kernel.hook('peripheral_detach', function(_, eventData)
local side = eventData[1]
if side then
local dev = Util.find(device, 'side', side)
if dev then
os.queueEvent('device_detach', dev.name)
device[dev.name] = nil
end
end
local side = eventData[1]
if side then
local dev = Util.find(device, 'side', side)
if dev then
os.queueEvent('device_detach', dev.name)
device[dev.name] = nil
end
end
end)
kernel.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
@@ -68,38 +68,38 @@ kernel.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
end
-- and fire hotkeys
local hotkey = Input:translate(event, eventData[1], eventData[2])
local hotkey = Input:translate(event, eventData[1], eventData[2])
if hotkey and keyboard.hotkeys[hotkey] then
keyboard.hotkeys[hotkey](event, eventData)
end
if hotkey and keyboard.hotkeys[hotkey.code] then
keyboard.hotkeys[hotkey.code](event, eventData)
end
end)
kernel.hook({ 'mouse_click', 'mouse_up', 'mouse_drag' }, function(event, eventData)
local button = eventData[1]
if event == 'mouse_click' then
mouse.state[button] = true
else
if not mouse.state[button] then
return true -- ensure mouse ups are only generated if a mouse down was sent
end
if event == 'mouse_up' then
mouse.state[button] = nil
end
end
local button = eventData[1]
if event == 'mouse_click' then
mouse.state[button] = true
else
if not mouse.state[button] then
return true -- ensure mouse ups are only generated if a mouse down was sent
end
if event == 'mouse_up' then
mouse.state[button] = nil
end
end
end)
kernel.hook('kernel_focus', function()
Util.clear(keyboard.state)
Util.clear(mouse.state)
Util.clear(keyboard.state)
Util.clear(mouse.state)
end)
function keyboard.addHotkey(code, fn)
keyboard.hotkeys[code] = fn
keyboard.hotkeys[code] = fn
end
function keyboard.removeHotkey(code)
keyboard.hotkeys[code] = nil
keyboard.hotkeys[code] = nil
end
kernel.hook('monitor_touch', function(event, eventData)

View File

@@ -1,8 +1,8 @@
if fs.native then
return
return
end
_G.requireInjector()
_G.requireInjector(_ENV)
local Util = require('util')
local fs = _G.fs
@@ -13,330 +13,330 @@ local fstypes = { }
local nativefs = { }
for k,fn in pairs(fs) do
if type(fn) == 'function' then
nativefs[k] = function(node, ...)
return fn(...)
end
end
if type(fn) == 'function' then
nativefs[k] = function(node, ...)
return fn(...)
end
end
end
function nativefs.list(node, dir)
local files
if fs.native.isDir(dir) then
files = fs.native.list(dir)
end
local files
if fs.native.isDir(dir) then
files = fs.native.list(dir)
end
local function inList(l, e)
for _,v in ipairs(l) do
if v == e then
return true
end
end
end
local function inList(l, e)
for _,v in ipairs(l) do
if v == e then
return true
end
end
end
if dir == node.mountPoint and node.nodes then
files = files or { }
for k in pairs(node.nodes) do
if not inList(files, k) then
table.insert(files, k)
end
end
end
if dir == node.mountPoint and node.nodes then
files = files or { }
for k in pairs(node.nodes) do
if not inList(files, k) then
table.insert(files, k)
end
end
end
if not files then
error('Not a directory', 2)
end
if not files then
error('Not a directory', 2)
end
return files
return files
end
function nativefs.getSize(node, dir, recursive)
if recursive and fs.native.isDir(dir) then
local function sum(dir)
local total = 0
local files = fs.native.list(dir)
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
if fs.native.isDir(fullName) then
total = total + sum(fullName)
else
total = total + fs.native.getSize(fullName)
end
end
return total
end
return sum(dir)
end
if node.mountPoint == dir and node.nodes then
return 0
end
return fs.native.getSize(dir)
if recursive and fs.native.isDir(dir) then
local function sum(dir)
local total = 0
local files = fs.native.list(dir)
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
if fs.native.isDir(fullName) then
total = total + sum(fullName)
else
total = total + fs.native.getSize(fullName)
end
end
return total
end
return sum(dir)
end
if node.mountPoint == dir and node.nodes then
return 0
end
return fs.native.getSize(dir)
end
function nativefs.isDir(node, dir)
if node.mountPoint == dir then
return not not node.nodes
end
return fs.native.isDir(dir)
if node.mountPoint == dir then
return not not node.nodes
end
return fs.native.isDir(dir)
end
function nativefs.exists(node, dir)
if node.mountPoint == dir then
return true
end
return fs.native.exists(dir)
if node.mountPoint == dir then
return true
end
return fs.native.exists(dir)
end
function nativefs.delete(node, dir)
if node.mountPoint == dir then
fs.unmount(dir)
else
fs.native.delete(dir)
end
if node.mountPoint == dir then
fs.unmount(dir)
else
fs.native.delete(dir)
end
end
fstypes.nativefs = nativefs
fs.nodes = {
fs = nativefs,
mountPoint = '',
fstype = 'nativefs',
nodes = { },
fs = nativefs,
mountPoint = '',
fstype = 'nativefs',
nodes = { },
}
local function splitpath(path)
local parts = { }
for match in string.gmatch(path, "[^/]+") do
table.insert(parts, match)
end
return parts
local parts = { }
for match in string.gmatch(path, "[^/]+") do
table.insert(parts, match)
end
return parts
end
local function getNode(dir)
local cd = fs.combine(dir, '')
local parts = splitpath(cd)
local node = fs.nodes
local cd = fs.combine(dir, '')
local parts = splitpath(cd)
local node = fs.nodes
for _,d in ipairs(parts) do
if node.nodes and node.nodes[d] then
node = node.nodes[d]
else
break
end
end
for _,d in ipairs(parts) do
if node.nodes and node.nodes[d] then
node = node.nodes[d]
else
break
end
end
return node
return node
end
local methods = { 'delete', 'getFreeSpace', 'exists', 'isDir', 'getSize',
'isReadOnly', 'makeDir', 'getDrive', 'list', 'open' }
'isReadOnly', 'makeDir', 'getDrive', 'list', 'open' }
for _,m in pairs(methods) do
fs[m] = function(dir, ...)
dir = fs.combine(dir or '', '')
local node = getNode(dir)
return node.fs[m](node, dir, ...)
end
fs[m] = function(dir, ...)
dir = fs.combine(dir or '', '')
local node = getNode(dir)
return node.fs[m](node, dir, ...)
end
end
function fs.complete(partial, dir, includeFiles, includeSlash)
dir = fs.combine(dir, '')
local node = getNode(dir)
if node.fs.complete then
return node.fs.complete(node, partial, dir, includeFiles, includeSlash)
end
return fs.native.complete(partial, dir, includeFiles, includeSlash)
dir = fs.combine(dir, '')
local node = getNode(dir)
if node.fs.complete then
return node.fs.complete(node, partial, dir, includeFiles, includeSlash)
end
return fs.native.complete(partial, dir, includeFiles, includeSlash)
end
function fs.listEx(dir)
local node = getNode(dir)
if node.fs.listEx then
return node.fs.listEx(node, dir)
end
local node = getNode(dir)
if node.fs.listEx then
return node.fs.listEx(node, dir)
end
local t = { }
local files = node.fs.list(node, dir)
local t = { }
local files = node.fs.list(node, dir)
pcall(function()
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
local file = {
name = f,
isDir = fs.isDir(fullName),
isReadOnly = fs.isReadOnly(fullName),
}
if not file.isDir then
file.size = fs.getSize(fullName)
end
table.insert(t, file)
end
end)
return t
pcall(function()
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
local file = {
name = f,
isDir = fs.isDir(fullName),
isReadOnly = fs.isReadOnly(fullName),
}
if not file.isDir then
file.size = fs.getSize(fullName)
end
table.insert(t, file)
end
end)
return t
end
function fs.copy(s, t)
local sp = getNode(s)
local tp = getNode(t)
if sp == tp and sp.fs.copy then
return sp.fs.copy(sp, s, t)
end
local sp = getNode(s)
local tp = getNode(t)
if sp == tp and sp.fs.copy then
return sp.fs.copy(sp, s, t)
end
if fs.exists(t) then
error('File exists')
end
if fs.exists(t) then
error('File exists')
end
if fs.isDir(s) then
fs.makeDir(t)
local list = fs.list(s)
for _,f in ipairs(list) do
fs.copy(fs.combine(s, f), fs.combine(t, f))
end
if fs.isDir(s) then
fs.makeDir(t)
local list = fs.list(s)
for _,f in ipairs(list) do
fs.copy(fs.combine(s, f), fs.combine(t, f))
end
else
local sf = Util.readFile(s)
if not sf then
error('No such file')
end
else
local sf = Util.readFile(s)
if not sf then
error('No such file')
end
Util.writeFile(t, sf)
end
Util.writeFile(t, sf)
end
end
function fs.find(spec) -- not optimized
-- local node = getNode(spec)
-- local files = node.fs.find(node, spec)
local files = { }
-- method from https://github.com/N70/deltaOS/blob/dev/vfs
local function recurse_spec(results, path, spec)
local segment = spec:match('([^/]*)'):gsub('/', '')
local pattern = '^' .. segment:gsub("[%.%[%]%(%)%%%+%-%?%^%$]","%%%1"):gsub("%z","%%z"):gsub("%*","[^/]-") .. '$'
if fs.isDir(path) then
for _, file in ipairs(fs.list(path)) do
if file:match(pattern) then
local f = fs.combine(path, file)
if spec == segment then
table.insert(results, f)
end
if fs.isDir(f) then
recurse_spec(results, f, spec:sub(#segment + 2))
end
end
end
end
end
recurse_spec(files, '', spec)
table.sort(files)
local files = { }
-- method from https://github.com/N70/deltaOS/blob/dev/vfs
local function recurse_spec(results, path, spec)
local segment = spec:match('([^/]*)'):gsub('/', '')
local pattern = '^' .. segment:gsub("[%.%[%]%(%)%%%+%-%?%^%$]","%%%1"):gsub("%z","%%z"):gsub("%*","[^/]-") .. '$'
if fs.isDir(path) then
for _, file in ipairs(fs.list(path)) do
if file:match(pattern) then
local f = fs.combine(path, file)
if spec == segment then
table.insert(results, f)
end
if fs.isDir(f) then
recurse_spec(results, f, spec:sub(#segment + 2))
end
end
end
end
end
recurse_spec(files, '', spec)
table.sort(files)
return files
return files
end
function fs.move(s, t)
local sp = getNode(s)
local tp = getNode(t)
if sp == tp and sp.fs.move then
return sp.fs.move(sp, s, t)
end
fs.copy(s, t)
fs.delete(s)
local sp = getNode(s)
local tp = getNode(t)
if sp == tp and sp.fs.move then
return sp.fs.move(sp, s, t)
end
fs.copy(s, t)
fs.delete(s)
end
local function getfstype(fstype)
local vfs = fstypes[fstype]
if not vfs then
vfs = require('fs.' .. fstype)
fs.registerType(fstype, vfs)
end
return vfs
local vfs = fstypes[fstype]
if not vfs then
vfs = require('fs.' .. fstype)
fs.registerType(fstype, vfs)
end
return vfs
end
function fs.mount(path, fstype, ...)
local vfs = getfstype(fstype)
if not vfs then
error('Invalid file system type')
end
local node = vfs.mount(path, ...)
if node then
local parts = splitpath(path)
local targetName = table.remove(parts, #parts)
local vfs = getfstype(fstype)
if not vfs then
error('Invalid file system type')
end
local node = vfs.mount(path, ...)
if node then
local parts = splitpath(path)
local targetName = table.remove(parts, #parts)
local tp = fs.nodes
for _,d in ipairs(parts) do
if not tp.nodes then
tp.nodes = { }
end
if not tp.nodes[d] then
tp.nodes[d] = Util.shallowCopy(tp)
tp.nodes[d].nodes = { }
tp.nodes[d].mountPoint = fs.combine(tp.mountPoint, d)
end
tp = tp.nodes[d]
end
local tp = fs.nodes
for _,d in ipairs(parts) do
if not tp.nodes then
tp.nodes = { }
end
if not tp.nodes[d] then
tp.nodes[d] = Util.shallowCopy(tp)
tp.nodes[d].nodes = { }
tp.nodes[d].mountPoint = fs.combine(tp.mountPoint, d)
end
tp = tp.nodes[d]
end
node.fs = vfs
node.fstype = fstype
if not targetName then
node.mountPoint = ''
fs.nodes = node
else
node.mountPoint = fs.combine(tp.mountPoint, targetName)
tp.nodes[targetName] = node
end
end
return node
node.fs = vfs
node.fstype = fstype
if not targetName then
node.mountPoint = ''
fs.nodes = node
else
node.mountPoint = fs.combine(tp.mountPoint, targetName)
tp.nodes[targetName] = node
end
end
return node
end
function fs.loadTab(path)
local mounts = Util.readFile(path)
if mounts then
for _,l in ipairs(Util.split(mounts)) do
if l:sub(1, 1) ~= '#' then
local s, m = pcall(function()
fs.mount(table.unpack(Util.matches(l)))
end)
if not s then
_G.printError('Mount failed')
_G.printError(l)
_G.printError(m)
end
end
end
end
local mounts = Util.readFile(path)
if mounts then
for _,l in ipairs(Util.split(mounts)) do
if l:sub(1, 1) ~= '#' then
local s, m = pcall(function()
fs.mount(table.unpack(Util.matches(l)))
end)
if not s then
_G.printError('Mount failed')
_G.printError(l)
_G.printError(m)
end
end
end
end
end
local function getNodeByParts(parts)
local node = fs.nodes
local node = fs.nodes
for _,d in ipairs(parts) do
if not node.nodes[d] then
return
end
node = node.nodes[d]
end
return node
for _,d in ipairs(parts) do
if not node.nodes[d] then
return
end
node = node.nodes[d]
end
return node
end
function fs.unmount(path)
local parts = splitpath(path)
local targetName = table.remove(parts, #parts)
local parts = splitpath(path)
local targetName = table.remove(parts, #parts)
local node = getNodeByParts(parts)
local node = getNodeByParts(parts)
if node and node.nodes[targetName] then
node.nodes[targetName] = nil
end
if node and node.nodes[targetName] then
node.nodes[targetName] = nil
end
end
function fs.registerType(name, fs)
fstypes[name] = fs
fstypes[name] = fs
end
function fs.getTypes()
return fstypes
return fstypes
end
function fs.restore()
local native = fs.native
Util.clear(fs)
Util.merge(fs, native)
local native = fs.native
Util.clear(fs)
Util.merge(fs, native)
end

View File

@@ -2,14 +2,14 @@ local os = _G.os
-- Default label
if not os.getComputerLabel() then
local id = os.getComputerID()
if _G.turtle then
os.setComputerLabel('turtle_' .. id)
elseif _G.pocket then
os.setComputerLabel('pocket_' .. id)
elseif _G.commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end
local id = os.getComputerID()
if _G.turtle then
os.setComputerLabel('turtle_' .. id)
elseif _G.pocket then
os.setComputerLabel('pocket_' .. id)
elseif _G.commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end
end

View File

@@ -1,4 +1,4 @@
_G.requireInjector()
_G.requireInjector(_ENV)
local Util = require('util')
@@ -7,32 +7,32 @@ local os = _G.os
local shell = _ENV.shell
if not fs.exists('usr/apps') then
fs.makeDir('usr/apps')
fs.makeDir('usr/apps')
end
if not fs.exists('usr/autorun') then
fs.makeDir('usr/autorun')
fs.makeDir('usr/autorun')
end
if not fs.exists('usr/config/fstab') then
Util.writeFile('usr/config/fstab',
'usr gitfs kepler155c/opus-apps/' .. os.getenv('BRANCH'))
Util.writeFile('usr/config/fstab',
'usr gitfs kepler155c/opus-apps/' .. os.getenv('BRANCH'))
end
if not fs.exists('usr/config/shell') then
Util.writeTable('usr/config/shell', {
aliases = shell.aliases(),
path = 'usr/apps:sys/apps:' .. shell.path(),
lua_path = 'sys/apis:usr/apis',
})
Util.writeTable('usr/config/shell', {
aliases = shell.aliases(),
path = 'usr/apps:sys/apps:' .. shell.path(),
lua_path = 'sys/apis:usr/apis',
})
end
local config = Util.readTable('usr/config/shell')
if config.aliases then
for k in pairs(shell.aliases()) do
shell.clearAlias(k)
end
for k,v in pairs(config.aliases) do
shell.setAlias(k, v)
end
for k in pairs(shell.aliases()) do
shell.clearAlias(k)
end
for k,v in pairs(config.aliases) do
shell.setAlias(k, v)
end
end
shell.setPath(config.path)
os.setenv('LUA_PATH', config.lua_path)

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
_G.requireInjector()
_G.requireInjector(_ENV)
local Config = require('config')
local Util = require('util')
@@ -25,367 +25,371 @@ shell.setEnv('multishell', multishell)
multishell.term = parentTerm --deprecated
local config = {
standard = {
textColor = colors.lightGray,
tabBarTextColor = colors.lightGray,
focusTextColor = colors.white,
backgroundColor = colors.gray,
tabBarBackgroundColor = colors.gray,
focusBackgroundColor = colors.gray,
},
color = {
textColor = colors.lightGray,
tabBarTextColor = colors.lightGray,
focusTextColor = colors.white,
backgroundColor = colors.gray,
tabBarBackgroundColor = colors.gray,
focusBackgroundColor = colors.gray,
},
standard = {
textColor = colors.lightGray,
tabBarTextColor = colors.lightGray,
focusTextColor = colors.white,
backgroundColor = colors.gray,
tabBarBackgroundColor = colors.gray,
focusBackgroundColor = colors.gray,
},
color = {
textColor = colors.lightGray,
tabBarTextColor = colors.lightGray,
focusTextColor = colors.white,
backgroundColor = colors.gray,
tabBarBackgroundColor = colors.gray,
focusBackgroundColor = colors.gray,
},
}
Config.load('multishell', config)
local _colors = parentTerm.isColor() and config.color or config.standard
local function redrawMenu()
if not tabsDirty then
os.queueEvent('multishell_redraw')
tabsDirty = true
end
if not tabsDirty then
os.queueEvent('multishell_redraw')
tabsDirty = true
end
end
function multishell.getFocus()
local currentTab = kernel.getFocused()
return currentTab.uid
local currentTab = kernel.getFocused()
return currentTab.uid
end
function multishell.setFocus(tabId)
return kernel.raise(tabId)
return kernel.raise(tabId)
end
function multishell.getTitle(tabId)
local tab = kernel.find(tabId)
return tab and tab.title
local tab = kernel.find(tabId)
return tab and tab.title
end
function multishell.setTitle(tabId, title)
local tab = kernel.find(tabId)
if tab then
tab.title = title
redrawMenu()
end
local tab = kernel.find(tabId)
if tab then
tab.title = title
redrawMenu()
end
end
function multishell.getCurrent()
local runningTab = kernel.getCurrent()
return runningTab and runningTab.uid
local runningTab = kernel.getCurrent()
return runningTab and runningTab.uid
end
function multishell.getTab(tabId)
return kernel.find(tabId)
return kernel.find(tabId)
end
function multishell.terminate(tabId)
os.queueEvent('multishell_terminate', tabId)
os.queueEvent('multishell_terminate', tabId)
end
function multishell.getTabs()
return kernel.routines
return kernel.routines
end
function multishell.launch( tProgramEnv, sProgramPath, ... )
-- backwards compatibility
return multishell.openTab({
env = tProgramEnv,
path = sProgramPath,
args = { ... },
})
-- backwards compatibility
return multishell.openTab({
env = tProgramEnv,
path = sProgramPath,
args = { ... },
})
end
function multishell.openTab(tab)
if not tab.title and tab.path then
tab.title = fs.getName(tab.path):match('([^%.]+)')
end
tab.title = tab.title or 'untitled'
tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false)
tab.terminal = tab.terminal or tab.window
if not tab.title and tab.path then
tab.title = fs.getName(tab.path):match('([^%.]+)')
end
tab.title = tab.title or 'untitled'
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)
local routine = kernel.newRoutine(tab)
routine.co = coroutine.create(function()
local result, err
routine.co = coroutine.create(function()
local result, err
if tab.fn then
result, err = Util.runFunction(routine.env, tab.fn, table.unpack(tab.args or { } ))
elseif tab.path then
result, err = Util.run(routine.env, tab.path, table.unpack(tab.args or { } ))
else
err = 'multishell: invalid tab'
end
if tab.fn then
result, err = Util.runFunction(routine.env, tab.fn, table.unpack(tab.args or { } ))
elseif tab.path then
result, err = Util.run(routine.env, tab.path, table.unpack(tab.args or { } ))
else
err = 'multishell: invalid tab'
end
if not result and err and err ~= 'Terminated' then
if err then
printError(tostring(err))
end
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
break
end
end
end
end)
if not result and err and err ~= 'Terminated' then
if err then
printError(tostring(err))
end
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
break
end
end
end
end)
kernel.launch(routine)
kernel.launch(routine)
if tab.focused then
multishell.setFocus(routine.uid)
else
redrawMenu()
end
return routine.uid
if tab.focused then
multishell.setFocus(routine.uid)
else
redrawMenu()
end
return routine.uid
end
function multishell.hideTab(tabId)
local tab = kernel.find(tabId)
if tab then
tab.hidden = true
kernel.lower(tab.uid)
redrawMenu()
end
local tab = kernel.find(tabId)
if tab then
tab.hidden = true
kernel.lower(tab.uid)
redrawMenu()
end
end
function multishell.unhideTab(tabId)
local tab = kernel.find(tabId)
if tab then
tab.hidden = false
redrawMenu()
end
local tab = kernel.find(tabId)
if tab then
tab.hidden = false
redrawMenu()
end
end
function multishell.getCount()
return #kernel.routines
return #kernel.routines
end
kernel.hook('kernel_focus', function(_, eventData)
local previous = eventData[2]
if previous then
local routine = kernel.find(previous)
if routine and routine.window then
routine.window.setVisible(false)
if routine.hidden then
kernel.lower(previous)
end
end
end
local previous = eventData[2]
if previous then
local routine = kernel.find(previous)
if routine and routine.window then
routine.window.setVisible(false)
if routine.hidden then
kernel.lower(previous)
end
end
end
local focused = kernel.find(eventData[1])
if focused and focused.window then
focused.window.setVisible(true)
end
local focused = kernel.find(eventData[1])
if focused and focused.window then
focused.window.setVisible(true)
end
redrawMenu()
redrawMenu()
end)
kernel.hook('multishell_terminate', function(_, eventData)
local tab = kernel.find(eventData[1])
if tab and not tab.isOverview then
if coroutine.status(tab.co) ~= 'dead' then
tab:resume("terminate")
end
end
return true
local tab = kernel.find(eventData[1])
if tab and not tab.isOverview then
if coroutine.status(tab.co) ~= 'dead' then
tab:resume("terminate")
end
end
return true
end)
kernel.hook('terminate', function()
return kernel.getFocused().isOverview
end)
kernel.hook('multishell_redraw', function()
tabsDirty = false
tabsDirty = false
local function write(x, text, bg, fg)
parentTerm.setBackgroundColor(bg)
parentTerm.setTextColor(fg)
parentTerm.setCursorPos(x, 1)
parentTerm.write(text)
end
local function write(x, text, bg, fg)
parentTerm.setBackgroundColor(bg)
parentTerm.setTextColor(fg)
parentTerm.setCursorPos(x, 1)
parentTerm.write(text)
end
local bg = _colors.tabBarBackgroundColor
parentTerm.setBackgroundColor(bg)
parentTerm.setCursorPos(1, 1)
parentTerm.clearLine()
local bg = _colors.tabBarBackgroundColor
parentTerm.setBackgroundColor(bg)
parentTerm.setCursorPos(1, 1)
parentTerm.clearLine()
local currentTab = kernel.getFocused()
local currentTab = kernel.getFocused()
for _,tab in pairs(kernel.routines) do
if tab.hidden and tab ~= currentTab then
tab.width = 0
else
tab.width = #tab.title + 1
end
end
for _,tab in pairs(kernel.routines) do
if tab.hidden and tab ~= currentTab then
tab.width = 0
else
tab.width = #tab.title + 1
end
end
local function width()
local tw = 0
Util.each(kernel.routines, function(t) tw = tw + t.width end)
return tw
end
local function width()
local tw = 0
Util.each(kernel.routines, function(t) tw = tw + t.width end)
return tw
end
while width() > w - 3 do
local tab = select(2,
Util.spairs(kernel.routines, function(a, b) return a.width > b.width end)())
tab.width = tab.width - 1
end
while width() > w - 3 do
local tab = select(2,
Util.spairs(kernel.routines, function(a, b) return a.width > b.width end)())
tab.width = tab.width - 1
end
local function compareTab(a, b)
if a.hidden then return false end
return b.hidden or a.uid < b.uid
end
local function compareTab(a, b)
if a.hidden then return false end
return b.hidden or a.uid < b.uid
end
local tabX = 0
for _,tab in Util.spairs(kernel.routines, compareTab) do
if tab.width > 0 then
tab.sx = tabX + 1
tab.ex = tabX + tab.width
tabX = tabX + tab.width
if tab ~= currentTab then
write(tab.sx, tab.title:sub(1, tab.width - 1),
_colors.backgroundColor, _colors.textColor)
end
end
end
local tabX = 0
for _,tab in Util.spairs(kernel.routines, compareTab) do
if tab.width > 0 then
tab.sx = tabX + 1
tab.ex = tabX + tab.width
tabX = tabX + tab.width
if tab ~= currentTab then
write(tab.sx, tab.title:sub(1, tab.width - 1),
_colors.backgroundColor, _colors.textColor)
end
end
end
if currentTab then
write(currentTab.sx - 1,
' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ',
_colors.focusBackgroundColor, _colors.focusTextColor)
if not currentTab.isOverview then
write(w, closeInd, _colors.backgroundColor, _colors.focusTextColor)
end
end
if currentTab then
write(currentTab.sx - 1,
' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ',
_colors.focusBackgroundColor, _colors.focusTextColor)
if not currentTab.isOverview then
write(w, closeInd, _colors.backgroundColor, _colors.focusTextColor)
end
end
if currentTab and currentTab.window then
currentTab.window.restoreCursor()
end
if currentTab and currentTab.window then
currentTab.window.restoreCursor()
end
return true
return true
end)
kernel.hook('term_resize', function(_, eventData)
if not eventData[1] then --- TEST
w,h = parentTerm.getSize()
if not eventData[1] then --- TEST
w,h = parentTerm.getSize()
local windowHeight = h-1
local windowHeight = h-1
for _,key in pairs(Util.keys(kernel.routines)) do
local tab = kernel.routines[key]
local x,y = tab.window.getCursorPos()
if y > windowHeight then
tab.window.scroll(y - windowHeight)
tab.window.setCursorPos(x, windowHeight)
end
tab.window.reposition(1, 2, w, windowHeight)
end
for _,key in pairs(Util.keys(kernel.routines)) do
local tab = kernel.routines[key]
local x,y = tab.window.getCursorPos()
if y > windowHeight then
tab.window.scroll(y - windowHeight)
tab.window.setCursorPos(x, windowHeight)
end
tab.window.reposition(1, 2, w, windowHeight)
end
redrawMenu()
end
redrawMenu()
end
end)
kernel.hook('mouse_click', function(_, eventData)
local x, y = eventData[2], eventData[3]
local x, y = eventData[2], eventData[3]
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
else
for _,tab in pairs(kernel.routines) do
if not tab.hidden and tab.sx then
if x >= tab.sx and x <= tab.ex then
multishell.setFocus(tab.uid)
break
end
end
end
end
return true
end
eventData[3] = eventData[3] - 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
else
for _,tab in pairs(kernel.routines) do
if not tab.hidden and tab.sx then
if x >= tab.sx and x <= tab.ex then
multishell.setFocus(tab.uid)
break
end
end
end
end
return true
end
eventData[3] = eventData[3] - 1
end)
kernel.hook({ 'mouse_up', 'mouse_drag' }, function(_, eventData)
eventData[3] = eventData[3] - 1
eventData[3] = eventData[3] - 1
end)
kernel.hook('mouse_scroll', function(_, eventData)
if eventData[3] == 1 then
return true
end
eventData[3] = eventData[3] - 1
if eventData[3] == 1 then
return true
end
eventData[3] = eventData[3] - 1
end)
local function startup()
local success = true
local success = true
local function runDir(directory, open)
if not fs.exists(directory) then
return true
end
local function runDir(directory, open)
if not fs.exists(directory) then
return true
end
local files = fs.list(directory)
table.sort(files)
local files = fs.list(directory)
table.sort(files)
for _,file in ipairs(files) do
os.sleep(0)
local result, err = open(directory .. '/' .. file)
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)
end
term.write('[PASS] ')
term.setTextColor(colors.white)
term.write(fs.combine(directory, file))
print()
else
if term.isColor() then
term.setTextColor(colors.red)
end
term.write('[FAIL] ')
term.setTextColor(colors.white)
term.write(fs.combine(directory, file))
if err then
_G.printError('\n' .. err)
end
print()
success = false
end
end
end
if result then
if term.isColor() then
term.setTextColor(colors.green)
end
term.write('[PASS] ')
term.setTextColor(colors.white)
term.write(fs.combine(directory, file))
print()
else
if term.isColor() then
term.setTextColor(colors.red)
end
term.write('[FAIL] ')
term.setTextColor(colors.white)
term.write(fs.combine(directory, file))
if err then
_G.printError('\n' .. err)
end
print()
success = false
end
end
end
runDir('sys/autorun', shell.run)
runDir('usr/autorun', shell.run)
runDir('sys/autorun', shell.run)
runDir('usr/autorun', shell.run)
if not success then
multishell.setFocus(multishell.getCurrent())
printError('\nA startup program has errored')
os.pullEvent('terminate')
end
if not success then
multishell.setFocus(multishell.getCurrent())
printError('\nA startup program has errored')
os.pullEvent('terminate')
end
end
kernel.hook('kernel_ready', function()
overviewId = multishell.openTab({
path = 'sys/apps/Overview.lua',
isOverview = true,
focused = true,
title = '+',
})
overviewId = multishell.openTab({
path = 'sys/apps/Overview.lua',
isOverview = true,
focused = true,
title = '+',
})
multishell.openTab({
fn = startup,
title = 'Autorun',
})
multishell.openTab({
fn = startup,
title = 'Autorun',
})
end)