OC-KittenOS/code/apps/svc-t.lua

159 lines
3.2 KiB
Lua

-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-t.lua : terminal
local _, _, retTbl, title = ...
assert(retTbl, "need to alert creator")
if title ~= nil then
assert(type(title) == "string", "title must be string")
end
local function rW()
return string.format("%04x", math.random(0, 65535))
end
local id = "svc.t/" .. rW() .. rW() .. rW() .. rW()
local closeNow = false
local tReg = neo.requireAccess("r." .. id, "registration")
-- unicode.safeTextFormat'd lines
local console = {}
for i = 1, 14 do
console[i] = (" "):rep(40)
end
local l15 = ""
--++++++++++++++++++++++++++++++++++++++++
-- sW must not go below 3.
-- sH must not go below 2.
local sW, sH = 40, 15
local windows = neo.requireAccess("x.neo.pub.window", "windows")
local window = windows(sW, sH, title)
local function fmtLine(s)
s = unicode.safeTextFormat(s)
local l = unicode.len(s)
return unicode.sub(s .. (" "):rep(sW - l), -sW)
end
local function line(i)
if i ~= sH then
assert(console[i], "console" .. i)
window.span(1, i, fmtLine(console[i]), 0xFFFFFF, 0)
else
window.span(1, i, fmtLine(l15), 0, 0xFFFFFF)
end
end
local function incoming(s)
local function shift(f)
for i = 1, #console - 1 do
console[i] = console[i + 1]
end
console[#console] = f
end
-- Need to break this safely.
shift("")
for i = 1, unicode.len(s) do
local ch = unicode.sub(s, i, i)
if unicode.wlen(console[#console] .. ch) > sW then
shift(" ")
end
console[#console] = console[#console] .. ch
end
for i = 1, #console do
line(i)
end
end
local sendSigs = {}
local function submitLine()
for _, v in pairs(sendSigs) do
v("line", l15)
end
l15 = ""
line(sH)
end
local function clipEnt(tx)
tx = tx:gsub("\r", "")
local ci = tx:find("\n") or (#tx + 1)
tx = tx:sub(1, ci - 1)
l15 = l15 .. tx
line(sH)
end
do
tReg(function (_, pid, sendSig)
sendSigs[pid] = sendSig
return {
id = "x." .. id,
pid = neo.pid,
line = function (text)
incoming(tostring(text))
end
}
end)
if retTbl then
coroutine.resume(coroutine.create(retTbl), {
access = "x." .. id,
close = function ()
closeNow = true
neo.scheduleTimer(0)
end
})
end
end
local control = false
while not closeNow do
local e = {coroutine.yield()}
if e[1] == "k.procdie" then
sendSigs[e[3]] = nil
elseif e[1] == "x.neo.pub.window" then
if e[3] == "close" then
break
elseif e[3] == "clipboard" then
clipEnt(e[4])
elseif e[3] == "key" then
if e[5] == 29 or e[5] == 157 then
control = e[6]
elseif e[6] then
if not control then
if e[4] == 8 or e[4] == 127 then
l15 = unicode.sub(l15, 1, -2)
elseif e[4] == 13 then
submitLine()
elseif e[4] >= 32 then
l15 = l15 .. unicode.char(e[4])
end
line(sH)
elseif e[5] == 203 and sW > 8 then
sW = sW - 1
window.setSize(sW, sH)
elseif e[5] == 200 and sH > 2 then
sH = sH - 1
table.remove(console, 1)
window.setSize(sW, sH)
elseif e[5] == 205 then
sW = sW + 1
window.setSize(sW, sH)
elseif e[5] == 208 then
sH = sH + 1
table.insert(console, 1, "")
window.setSize(sW, sH)
end
end
elseif e[3] == "line" then
line(e[4])
end
end
end