From f5ba0489b24e45419c53853283d69782966ab3a3 Mon Sep 17 00:00:00 2001 From: 20kdc Date: Sat, 28 Mar 2020 19:13:03 +0000 Subject: [PATCH] Start work on r9 with the basic terminal system design --- claw/code-claw.lua | 17 +++- code/apps/app-luashell.lua | 88 +++++++++++++++++++++ code/apps/svc-t.lua | 158 +++++++++++++++++++++++++++++++++++++ code/docs/logo.bmp | Bin 2598 -> 2598 bytes 4 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 code/apps/app-luashell.lua create mode 100644 code/apps/svc-t.lua diff --git a/claw/code-claw.lua b/claw/code-claw.lua index baacf03..13f4779 100644 --- a/claw/code-claw.lua +++ b/claw/code-claw.lua @@ -125,7 +125,7 @@ return { }, ["neo-logo"] = { desc = "KittenOS NEO Logo (data)", - v = 8, + v = 9, deps = { }, dirs = { @@ -175,6 +175,20 @@ return { "apps/svc-app-claw-worker.lua" }, }, + ["svc-t"] = { + desc = "KittenOS NEO Terminal System", + v = 9, + deps = { + "neo" + }, + dirs = { + "apps" + }, + files = { + "apps/svc-t.lua", + "apps/app-luashell.lua" + }, + }, ["neo-meta"] = { desc = "KittenOS NEO: Use 'All' to install to other disks", v = 5, @@ -190,6 +204,7 @@ return { "app-bmpview", "app-flash", "app-claw", + "svc-t", "app-wget" }, dirs = { diff --git a/code/apps/app-luashell.lua b/code/apps/app-luashell.lua new file mode 100644 index 0000000..7a9e198 --- /dev/null +++ b/code/apps/app-luashell.lua @@ -0,0 +1,88 @@ +-- This is released into the public domain. +-- No warranty is provided, implied or otherwise. + +local _, _, termId = ... +local ok = pcall(function () + assert(string.sub(termId, 1, 8) == "x.svc.t/") +end) +if not ok then + termId = nil + neo.executeAsync("svc-t", function (res) + termId = res.access + neo.scheduleTimer(0) + end, "luashell") + while not termId do + coroutine.yield() + end +end +TERM = neo.requireAccess(termId, "terminal") + +TERM.line("KittenOS NEO Lua Shell") + +print = function (...) + local n = {} + local s = {...} + for i = 1, #s do + local v = s[i] + if v == nil then + v = "nil" + end + table.insert(n, tostring(v)) + end + TERM.line(table.concat(n, " ")) +end + +local alive = true + +run = function (x, ...) + local subPid = neo.executeAsync(x, ...) + if not subPid then + subPid = neo.executeAsync("sys-t-" .. x, TERM.id, ...) + end + if not subPid then + subPid = neo.executeAsync("svc-t-" .. x, TERM.id, ...) + end + if not subPid then + subPid = neo.executeAsync("app-" .. x, TERM.id, ...) + end + if not subPid then + error("cannot find " .. x) + end + while true do + local e = {coroutine.yield()} + if e[1] == "k.procdie" then + if e[3] == TERM.pid then + alive = false + return + elseif e[3] == subPid then + return + end + end + end +end + +exit = function () + alive = false +end + +while alive do + local e = {coroutine.yield()} + if e[1] == "k.procdie" then + if e[3] == TERM.pid then + alive = false + end + elseif e[1] == TERM.id then + if e[2] == "line" then + TERM.line("> " .. e[3]) + local ok, err = pcall(function () + if e[3]:sub(1, 1) == "=" then + e[3] = "return " .. e[3]:sub(2) + end + print(assert(load(e[3]))()) + end) + if not ok then + TERM.line(tostring(err)) + end + end + end +end \ No newline at end of file diff --git a/code/apps/svc-t.lua b/code/apps/svc-t.lua new file mode 100644 index 0000000..543e88e --- /dev/null +++ b/code/apps/svc-t.lua @@ -0,0 +1,158 @@ +-- 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 diff --git a/code/docs/logo.bmp b/code/docs/logo.bmp index 3802fb1d37f26276634f3ee08d9188fee9be80d5..93650262707f61f08bbe5ade91574e1fa4fe045a 100644 GIT binary patch delta 35 mcmZ1`vP@*c31)6??un-j85t)2H3qRK8#AVY=*_bkyEy>8d5EeT%$