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:
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
@@ -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)
|
||||
|
Reference in New Issue
Block a user