1
0
mirror of https://github.com/kepler155c/opus synced 2024-12-24 15:40:26 +00:00

multishell hooks

This commit is contained in:
kepler155c@gmail.com 2017-10-14 03:41:54 -04:00
parent 153b0b86ff
commit 8b187f2813
8 changed files with 135 additions and 67 deletions

View File

@ -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)

View File

@ -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 = { ... }

View File

@ -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

View File

@ -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
end

View File

@ -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)

View File

@ -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'

View File

@ -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] = { }

View File

@ -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')