diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 7496f94..6de7bce 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -6,7 +6,6 @@ local Util = require('util') local _rep = string.rep local _sub = string.sub -local clipboard = _G.clipboard local colors = _G.colors local device = _G.device local fs = _G.fs @@ -1672,7 +1671,7 @@ function UI.Grid:eventHandler(event) end elseif event.type == 'copy' then if self.selected then - clipboard.setData(Util.tostring(self.selected)) + os.queueEvent('clipboard_copy', Util.tostring(self.selected)) end else return false @@ -2689,7 +2688,7 @@ function UI.TextEntry:eventHandler(event) return true elseif event.type == 'copy' then - clipboard.setData(self.value) + os.queueEvent('clipboard_copy', self.value) elseif event.type == 'paste' then local input = tostring(self.value) diff --git a/sys/apps/Lua.lua b/sys/apps/Lua.lua index de3b674..e46d836 100644 --- a/sys/apps/Lua.lua +++ b/sys/apps/Lua.lua @@ -7,13 +7,14 @@ local Peripheral = require('peripheral') local UI = require('ui') local Util = require('util') -local clipboard = _G.clipboard +local colors = _G.colors local multishell = _ENV.multishell +local os = _G.os local textutils = _G.textutils local sandboxEnv = setmetatable(Util.shallowCopy(_ENV), { __index = _G }) sandboxEnv.exit = function() Event.exitPullEvents() end -sandboxEnv._echo = function( ... ) return ... end +sandboxEnv._echo = function( ... ) return { ... } end injector(sandboxEnv) multishell.setTitle(multishell.getCurrent(), 'Lua') @@ -21,6 +22,7 @@ UI:configure('Lua', ...) local command = '' local history = History.load('usr/.lua_history', 25) +local extChars = Util.getVersion() > 1.76 local page = UI.Page { menuBar = UI.MenuBar { @@ -42,6 +44,10 @@ local page = UI.Page { [ 'control-space' ] = 'autocomplete', }, }, + indicator = UI.Text { + backgroundColor = colors.black, + y = 2, x = -1, width = 1, + }, grid = UI.ScrollingGrid { y = 3, columns = { @@ -54,6 +60,17 @@ local page = UI.Page { notification = UI.Notification(), } +function page.indicator:showResult(s) + local values = { + [ true ] = { c = colors.green, i = (extChars and '\003') or '+' }, + [ false ] = { c = colors.red, i = 'x' } + } + + self.textColor = values[s].c + self.value = values[s].i + self:draw() +end + function page:setPrompt(value, focus) self.prompt:setValue(value) self.prompt.scroll = 0 @@ -76,7 +93,6 @@ function page:enable() end local function autocomplete(env, oLine, x) - local sLine = oLine:sub(1, x) local nStartPos = sLine:find("[a-zA-Z0-9_%.]+$") if nStartPos then @@ -109,7 +125,6 @@ local function autocomplete(env, oLine, x) end function page:eventHandler(event) - if event.type == 'global' then self:setPrompt('', true) self:executeStatement('_G') @@ -220,7 +235,6 @@ function page:setResult(result) end function page.grid:eventHandler(event) - local entry = self:getSelected() local function commandAppend() @@ -255,8 +269,8 @@ function page.grid:eventHandler(event) page:setPrompt(commandAppend(), true) page:executeStatement(commandAppend()) elseif event.type == 'copy' then - if entry and clipboard then - clipboard.setData(entry.rawValue) + if entry then + os.queueEvent('clipboard_copy', entry.rawValue) end else return UI.ScrollingGrid.eventHandler(self, event) @@ -265,10 +279,16 @@ function page.grid:eventHandler(event) end function page:rawExecute(s) - local fn, m = load('return _echo(' ..s.. ');', 'lua', nil, sandboxEnv) + local fn, m + + fn = load('return (' ..s.. ')', 'lua', nil, sandboxEnv) + if fn then - m = { pcall(fn) } - fn = table.remove(m, 1) + fn = load('return {' ..s.. '}', 'lua', nil, sandboxEnv) + end + + if fn then + fn, m = pcall(fn) if #m == 1 then m = m[1] end @@ -284,7 +304,6 @@ function page:rawExecute(s) end function page:executeStatement(statement) - command = statement local s, m = self:rawExecute(command) @@ -298,6 +317,7 @@ function page:executeStatement(statement) self.notification:error(m, 5) end end + self.indicator:showResult(not not s) end local args = { ... } diff --git a/sys/apps/multishell b/sys/apps/multishell index ed967b1..278a7dc 100644 --- a/sys/apps/multishell +++ b/sys/apps/multishell @@ -27,6 +27,8 @@ local overviewTab local runningTab local tabsDirty = false local closeInd = '*' +local redrawTimer +local hooks = { } multishell.term = term.current() @@ -417,16 +419,38 @@ function multishell.getCount() return Util.size(tabs) end +function multishell.showMessage(text) + parentTerm.setCursorPos(3, 1) + parentTerm.setTextColor(_colors.textColor) + parentTerm.setBackgroundColor(_colors.backgroundColor) + if #text + 3 < w then + text = text .. string.rep(' ', w - #text - 3) + end + parentTerm.write(text) + redrawTimer = os.startTimer(2) + if currentTab then + currentTab.window.restoreCursor() + end +end + +function multishell.hook(event, fn) + if type(event) == table then + for _,v in pairs(event) do + multishell.hook(v, fn) + end + else + if not hooks[event] then + hooks[event] = { } + end + table.insert(hooks[event], 1, fn) + end +end + -- control-o - overview multishell.addHotkey(24, function() multishell.setFocus(overviewTab.tabId) end) --- control-t - toggle clipboard mode -multishell.addHotkey(20, function() - _G.clipboard.useInternal(not _G.clipboard.isInternal()) -end) - -- control-backspace multishell.addHotkey(14, function() local tabId = multishell.getFocus() @@ -512,11 +536,23 @@ while true do -- Get the event local tEventData = { os.pullEventRaw() } local sEvent = table.remove(tEventData, 1) + local passthrough = true if sEvent == 'key_up' then processKeyEvent(sEvent, tEventData[1]) end + if sEvent == 'timer' and tEventData[1] == redrawTimer then + redrawMenu() + end + + local hk = hooks[sEvent] + if hk then + for _,fn in pairs(hk) do + fn(sEvent, tEventData) + end + end + if sEvent == "term_resize" then -- Resize event w,h = parentTerm.getSize() @@ -535,11 +571,7 @@ while true do end elseif sEvent == "paste" then - if _G.clipboard.isInternal() then - resumeTab(currentTab, sEvent, { _G.clipboard.getText() or '' }) - else - resumeTab(currentTab, sEvent, tEventData) - end + resumeTab(currentTab, sEvent, tEventData) elseif sEvent == "char" or sEvent == "key" or @@ -599,7 +631,7 @@ while true do end end - else + elseif passthrough then -- Other event -- Passthrough to all processes for _,key in pairs(Util.keys(tabs)) do diff --git a/sys/apps/shell b/sys/apps/shell index b686461..68f757a 100644 --- a/sys/apps/shell +++ b/sys/apps/shell @@ -44,28 +44,21 @@ local function tokenise( ... ) return tWords end -local function run(env, command, ...) - if not command then - error('No such program') - end - - local isUrl = not not command:match("^(https?:)//(([^/:]+):?([0-9]*))(/?.*)$") - local path, runFn +local function run(env, ...) + local args = tokenise(...) + local command = table.remove(args, 1) or error('No such program') + local isUrl = not not command:match("^(https?:)") + local path, loadFn if isUrl then path = command - runFn = Util.loadUrl + loadFn = Util.loadUrl else - path = shell.resolveProgram(command) - runFn = loadfile + path = shell.resolveProgram(command) or error('No such program') + loadFn = loadfile end - if not path then - error('No such program') - end - - local fn, err = runFn(path, env) - + local fn, err = loadFn(path, env) if not fn then error(err) end @@ -80,7 +73,7 @@ local function run(env, command, ...) tProgramStack[#tProgramStack + 1] = path end - local r = { fn(table.unpack(tokenise(...))) } + local r = { fn(table.unpack(args)) } tProgramStack[#tProgramStack] = nil @@ -124,7 +117,6 @@ function shell.resolve( _sPath ) end function shell.resolveProgram( _sCommand ) - if tAliases[_sCommand] ~= nil then _sCommand = tAliases[_sCommand] end @@ -299,13 +291,15 @@ function shell.aliases() return tCopy end -function shell.newTab(tabInfo, path, ...) +function shell.newTab(tabInfo, ...) + local args = tokenise(...) + local path = table.remove(args, 1) path = shell.resolveProgram(path) if path then tabInfo.path = path tabInfo.env = sandboxEnv - tabInfo.args = tokenise(...) + tabInfo.args = args tabInfo.title = fs.getName(path) if path ~= 'sys/apps/shell' then @@ -661,10 +655,9 @@ while not bExit do end term.setTextColour(_colors.textColor) if #sLine > 0 then - local args = tokenise(sLine) - local result, err = shell.run(table.remove(args, 1), table.unpack(args)) + local result, err = shell.run(sLine) if not result and err then _G.printError(err) end end -end \ No newline at end of file +end diff --git a/sys/extensions/clipboard.lua b/sys/autorun/clipboard.lua similarity index 53% rename from sys/extensions/clipboard.lua rename to sys/autorun/clipboard.lua index e2ff628..df87bbe 100644 --- a/sys/extensions/clipboard.lua +++ b/sys/autorun/clipboard.lua @@ -1,10 +1,9 @@ -if _G.clipboard then - return -end - _G.requireInjector() + local Util = require('util') -local os = _G.os + +local multishell = _ENV.multishell +local os = _G.os local clipboard = { } @@ -32,8 +31,23 @@ end function clipboard.useInternal(mode) if mode ~= clipboard.internal then clipboard.internal = mode + local text = 'Clipboard (^m): ' .. ((mode and 'internal') or 'normal') + multishell.showMessage(text) os.queueEvent('clipboard_mode', mode) end end -_G.clipboard = clipboard +multishell.hook('clipboard_copy', function(_, args) + clipboard.setData(args[1]) +end) + +multishell.hook('paste', function(_, args) + if clipboard.isInternal() then + args[1] = clipboard.getText() or '' + end +end) + +-- control-m - clipboard mode +multishell.addHotkey(50, function() + clipboard.useInternal(not clipboard.isInternal()) +end) diff --git a/sys/boot/multishell.boot b/sys/boot/multishell.boot index ce2db5d..91fbacc 100644 --- a/sys/boot/multishell.boot +++ b/sys/boot/multishell.boot @@ -1,4 +1,9 @@ -- Loads the Opus environment regardless if the file system is local or not +local colors = _G.colors +local fs = _G.fs +local http = _G.http +local shell = _ENV.shell +local term = _G.term local w, h = term.getSize() term.setTextColor(colors.white) @@ -34,7 +39,7 @@ local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO local function makeEnv() local env = setmetatable({ }, { __index = _G }) for k,v in pairs(_ENV) do - env[k] = v + env[k] = v end return env end @@ -51,10 +56,10 @@ end local function runUrl(file, ...) local url = BASE .. '/' .. file - local h = http.get(url) - if h then - local fn = load(h.readAll(), url, nil, makeEnv()) - h.close() + local u = http.get(url) + if u then + local fn = load(u.readAll(), url, nil, makeEnv()) + u.close() if fn then return fn(...) end @@ -108,7 +113,7 @@ if config.aliases then end end shell.setPath(config.path) -LUA_PATH = config.lua_path +_ENV.LUA_PATH = config.lua_path -- extensions local dir = 'sys/extensions' diff --git a/sys/network/snmp.lua b/sys/network/snmp.lua index 123993e..5fd917d 100644 --- a/sys/network/snmp.lua +++ b/sys/network/snmp.lua @@ -3,6 +3,12 @@ local GPS = require('gps') local Socket = require('socket') local Util = require('util') +local device = _G.device +local multishell = _ENV.multishell +local network = _G.network +local os = _G.os +local turtle = _G.turtle + -- move this into gps api local gpsRequested local gpsLastPoint @@ -17,7 +23,7 @@ local function snmpConnection(socket) end if msg.type == 'reboot' then - os.reboot() + os.reboot() elseif msg.type == 'shutdown' then os.shutdown() @@ -26,20 +32,19 @@ local function snmpConnection(socket) socket:write('pong') elseif msg.type == 'script' then - local fn, msg = loadstring(msg.args, 'script') + local fn, err = loadstring(msg.args, 'script') if fn then multishell.openTab({ fn = fn, - env = getfenv(1), title = 'script', }) else - printError(msg) + _G.printError(err) end elseif msg.type == 'scriptEx' then local s, m = pcall(function() - local env = setmetatable(Util.shallowCopy(getfenv(1)), { __index = _G }) + local env = setmetatable(Util.shallowCopy(_ENV), { __index = _G }) local fn, m = load(msg.args, 'script', nil, env) if not fn then error(m) @@ -110,7 +115,7 @@ end) device.wireless_modem.open(999) print('discovery: listening on port 999') -Event.on('modem_message', function(e, s, sport, id, info, distance) +Event.on('modem_message', function(_, _, sport, id, info, distance) if sport == 999 and tonumber(id) and type(info) == 'table' then if not network[id] then network[id] = { } diff --git a/sys/services/chat.lua b/sys/services/chat.lua index 8ac7c45..4052f90 100644 --- a/sys/services/chat.lua +++ b/sys/services/chat.lua @@ -2,7 +2,7 @@ local device = _G.device local multishell = _ENV.multishell local os = _G.os -if device.wireless_modem then +if device.wireless_modem and false then multishell.setTitle(multishell.getCurrent(), 'Chat')