1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-23 10:58:06 +11:00

Pretend app-flash exists already, get rid of keymap module, make textedit usable without having to worry about keymap

This commit is contained in:
20kdc 2018-03-23 15:35:43 +00:00
parent 1802ec6464
commit 36afa760c4
5 changed files with 195 additions and 286 deletions

9
code/apps/app-flash.lua Normal file
View File

@ -0,0 +1,9 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
local event = require("event")(neo)
local neoux = require("neoux")(event, neo)
-- label
-- [ ]
-- <read><write>

View File

@ -5,24 +5,16 @@
-- This was textedit (femto) from KittenOS 'ported' to NEO. -- This was textedit (femto) from KittenOS 'ported' to NEO.
-- It also has fixes for bugs involving wide text, and runs faster due to the chars -> lines change. -- It also has fixes for bugs involving wide text, and runs faster due to the chars -> lines change.
local mapping, _ = unicode.keymap("ASQCVDJK")
local mappingFinal = {}
for i = 1, #mapping do
mappingFinal[i] = unicode.sub(mapping, i, i)
end
local lines = { local lines = {
"Neolithic: Text Editor", "Neolithic: Text Editor",
"Keymap " .. unicode.getKeymap() .. ", to correct, type", "F3, F4, F1: Load, Save, New",
" the alphabet in capitals.", "F5, F6, ^←: Copy, Paste, Delete Line",
"Then, restart the text editor.",
"^" .. mappingFinal[1] .. ", ^" .. mappingFinal[2] .. ", ^" .. mappingFinal[3] .. ": Load, Save, New",
"^" .. mappingFinal[4] .. ", ^" .. mappingFinal[5] .. ", ^" .. mappingFinal[6] .. ": Copy, Paste, Delete Line",
-- These two are meant to replace similar functionality in GNU Nano -- These two are meant to replace similar functionality in GNU Nano
-- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that), -- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that),
-- except fixing a UI flaw by instead making J responsible for resetting the append flag, -- except fixing a UI flaw by instead making J responsible for resetting the append flag,
-- so the user can more or less arbitrarily mash together lines -- so the user can more or less arbitrarily mash together lines
"^" .. mappingFinal[7] .. ": Reset 'append' flag for Cut Lines", "F7: Reset 'append' flag for Cut Lines",
"^" .. mappingFinal[8] .. ": Cut Line(s)", "F8: Cut Line(s)",
"^<arrows>: Resize Win", "^<arrows>: Resize Win",
"'^' is Control.", "'^' is Control.",
"Wide text & clipboard supported.", "Wide text & clipboard supported.",
@ -35,14 +27,7 @@ local lines = {
-- The way I have things setup is that you perform J then K(repeat) *instead*, which means you have to explicitly say "destroy current clipboard". -- The way I have things setup is that you perform J then K(repeat) *instead*, which means you have to explicitly say "destroy current clipboard".
local event = require("event")(neo) local event = require("event")(neo)
local clipboard = neo.requestAccess("x.neo.pub.clip.text") local clipsrc = neo.requireAccess("x.neo.pub.globals", "clipboard")
if not clipboard then
local clipboardData = ""
clipboard = {
copy = function (text) clipboardData = text end,
paste = function () return clipboardData end
}
end
local cursorX = 1 local cursorX = 1
local cursorY = math.ceil(#lines / 2) local cursorY = math.ceil(#lines / 2)
@ -207,8 +192,10 @@ local function ev_key(ka, kc, down)
ctrlFlag = down ctrlFlag = down
return false return false
end end
-- Action keys
if not down then return false end
if ctrlFlag then if ctrlFlag then
if not down then return false end -- Control Action Keys
if kc == 200 then -- Up if kc == 200 then -- Up
sH = sH - 1 sH = sH - 1
if sH == 0 then if sH == 0 then
@ -231,40 +218,87 @@ local function ev_key(ka, kc, down)
sW = sW + 1 sW = sW + 1
sW, sH = window.setSize(sW, sH) sW, sH = window.setSize(sW, sH)
end end
if kc == 31 then -- S if kc == 14 then -- ^Backspace
startSave() delLine()
return true
end end
if kc == 30 then -- A else
startLoad() -- Non-Control Action Keys
-- Basic Action Keys
if kc == 200 or kc == 201 then -- Go up one - go up page
local moveAmount = 1
if kc == 201 then
moveAmount = math.floor(sH / 2)
end
cursorY = cursorY - moveAmount
if cursorY < 1 then
cursorY = 1
end
clampCursorX()
return true
end end
if kc == 16 then -- Q if kc == 208 or kc == 209 then -- Go down one - go down page
local moveAmount = 1
if kc == 209 then
moveAmount = math.floor(sH / 2)
end
cursorY = cursorY + moveAmount
if cursorY > #lines then
cursorY = #lines
end
clampCursorX()
return true
end
if kc == 203 then
if cursorX > 1 then
cursorX = cursorX - 1
else
if cursorY > 1 then
cursorY = cursorY - 1
cursorX = unicode.len(lines[cursorY]) + 1
else
return false
end
end
return true
end
if kc == 205 then
cursorX = cursorX + 1
if clampCursorX() then
if cursorY < #lines then
cursorY = cursorY + 1
cursorX = 1
end
end
return true
end
-- Extra Non-Control Keys
if kc == 199 then
cursorX = 1
return true
end
if kc == 207 then
cursorX = unicode.len(lines[cursorY]) + 1
return true
end
-- Major Actions
if kc == 59 then -- F1
lines = {""} lines = {""}
cursorX = 1 cursorX = 1
cursorY = 1 cursorY = 1
return true return true
end end
if kc == 32 then -- D if kc == 61 then -- F3
delLine() startLoad()
return true
end end
if kc == 46 then -- C if kc == 62 then -- F4
clipboard.copy(lines[cursorY]) startSave()
end end
if kc == 36 then -- J if kc == 63 then -- F5
appendFlag = false clipsrc.setSetting("clipboard", lines[cursorY])
end end
if kc == 37 then -- K if kc == 64 then -- F6
if appendFlag then local tx = clipsrc.getSetting("clipboard") or ""
local base = clipboard.paste()
clipboard.copy(base .. "\n" .. delLine())
else
clipboard.copy(delLine())
end
appendFlag = true
return true
end
if kc == 47 then -- V
local tx = clipboard.paste()
local txi = tx:find("\n") local txi = tx:find("\n")
local nt = {} local nt = {}
while txi do while txi do
@ -278,85 +312,39 @@ local function ev_key(ka, kc, down)
end end
return true return true
end end
return false if kc == 65 then -- F7
end appendFlag = false
-- action keys
if not down then
return false
end
if kc == 200 or kc == 201 then -- Go up one - go up page
local moveAmount = 1
if kc == 201 then
moveAmount = math.floor(sH / 2)
end end
cursorY = cursorY - moveAmount if kc == 66 then -- F8
if cursorY < 1 then if appendFlag then
cursorY = 1 local base = clipsrc.getSetting("clipboard")
clipsrc.setSetting("clipboard", base .. "\n" .. delLine())
else
clipsrc.setSetting("clipboard", delLine())
end
appendFlag = true
return true
end end
clampCursorX()
return true
end end
if kc == 208 or kc == 209 then -- Go down one - go down page -- Letters
local moveAmount = 1 if ka ~= 0 then
if kc == 209 then if ka == 8 then
moveAmount = math.floor(sH / 2) if cursorX == 1 then
end if cursorY == 1 then
cursorY = cursorY + moveAmount return false
if cursorY > #lines then end
cursorY = #lines local l = table.remove(lines, cursorY)
end
clampCursorX()
return true
end
if kc == 203 then
if cursorX > 1 then
cursorX = cursorX - 1
else
if cursorY > 1 then
cursorY = cursorY - 1 cursorY = cursorY - 1
cursorX = unicode.len(lines[cursorY]) + 1 cursorX = unicode.len(lines[cursorY]) + 1
lines[cursorY] = lines[cursorY] .. l
else else
return false local a, b = splitCur()
a = unicode.sub(a, 1, unicode.len(a) - 1)
lines[cursorY] = a.. b
cursorX = cursorX - 1
end end
return true
end end
return true
end
if kc == 205 then
cursorX = cursorX + 1
if clampCursorX() then
if cursorY < #lines then
cursorY = cursorY + 1
cursorX = 1
end
end
return true
end
if kc == 199 then
cursorX = 1
return true
end
if kc == 207 then
cursorX = unicode.len(lines[cursorY]) + 1
return true
end
if ka == 8 then
if cursorX == 1 then
if cursorY == 1 then
return false
end
local l = table.remove(lines, cursorY)
cursorY = cursorY - 1
cursorX = unicode.len(lines[cursorY]) + 1
lines[cursorY] = lines[cursorY] .. l
else
local a, b = splitCur()
a = unicode.sub(a, 1, unicode.len(a) - 1)
lines[cursorY] = a.. b
cursorX = cursorX - 1
end
return true
end
if ka ~= 0 then
putLetter(unicode.char(ka)) putLetter(unicode.char(ka))
return true return true
end end

View File

@ -6,7 +6,7 @@
local donkonitSPProvider = neo.requireAccess("r.neo.sys.manage", "creating NEO core APIs") -- Restrict to s- local donkonitSPProvider = neo.requireAccess("r.neo.sys.manage", "creating NEO core APIs") -- Restrict to s-
-- Doesn't matter what calls this service, because there's a mutex here. -- Doesn't matter what calls this service, because there's a mutex here.
local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs") local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs")
local glacierDCProvider = neo.requireAccess("r.neo.sys.randr", "creating NEO core APIs") local glacierDCProvider = neo.requireAccess("r.neo.pub.globals", "creating NEO core APIs")
local computer = neo.requireAccess("k.computer", "shutting down") local computer = neo.requireAccess("k.computer", "shutting down")
local fs = neo.requireAccess("c.filesystem", "settings I/O") local fs = neo.requireAccess("c.filesystem", "settings I/O")
@ -14,6 +14,7 @@ local gpus = neo.requireAccess("c.gpu", "screen control")
local screens = neo.requireAccess("c.screen", "screen control") local screens = neo.requireAccess("c.screen", "screen control")
neo.requireAccess("s.h.component_added", "HW management") neo.requireAccess("s.h.component_added", "HW management")
neo.requireAccess("s.h.component_removed", "HW management") neo.requireAccess("s.h.component_removed", "HW management")
neo.requireAccess("s.h.key_down", "Keymap guesswork")
local function shutdownFin(reboot) local function shutdownFin(reboot)
-- any final actions donkonit needs to take here -- any final actions donkonit needs to take here
@ -39,6 +40,7 @@ local settings = {
-- The list of settings is here: -- The list of settings is here:
-- password -- password
password = "", password = "",
["pub.clipboard"] = "",
["sys-init.shell"] = "sys-everest", ["sys-init.shell"] = "sys-everest",
["run.sys-icecap"] = "yes", ["run.sys-icecap"] = "yes",
-- scr.w/h/d.<uuid> -- scr.w/h/d.<uuid>
@ -115,7 +117,7 @@ local function sRattle(name, val)
for _, v in pairs(targs) do for _, v in pairs(targs) do
v("set_setting", name, val) v("set_setting", name, val)
end end
if name:sub(1, 4) == "scr." then if name:sub(1, 4) == "scr." or name:sub(1, 4) == "pub." then
for k, v in pairs(targsDC) do for k, v in pairs(targsDC) do
if not targs[k] then if not targs[k] then
v("set_setting", name, val) v("set_setting", name, val)
@ -160,6 +162,7 @@ donkonitSPProvider(function (pkg, pid, sendSig)
end end
return s return s
end, end,
-- NOTE: REPLICATED IN GB
getSetting = function (name) getSetting = function (name)
if type(name) ~= "string" then error("Setting name must be string") end if type(name) ~= "string" then error("Setting name must be string") end
return settings[name] return settings[name]
@ -167,7 +170,7 @@ donkonitSPProvider(function (pkg, pid, sendSig)
delSetting = function (name) delSetting = function (name)
if type(name) ~= "string" then error("Setting name must be string") end if type(name) ~= "string" then error("Setting name must be string") end
local val = nil local val = nil
if name == "password" then val = "" end if name == "password" or name == "pub.clipboard" then val = "" end
settings[name] = val settings[name] = val
sRattle(name, val) sRattle(name, val)
pcall(saveSettings) pcall(saveSettings)
@ -181,8 +184,8 @@ donkonitSPProvider(function (pkg, pid, sendSig)
-- Monitor settings are applied on the transition to control. -- Monitor settings are applied on the transition to control.
sRattle(name, val) sRattle(name, val)
pcall(saveSettings) pcall(saveSettings)
--saveSettings()
end, end,
--
registerForShutdownEvent = function () registerForShutdownEvent = function ()
targsSD[pid] = sendSig targsSD[pid] = sendSig
end, end,
@ -338,7 +341,27 @@ glacierDCProvider(function (pkg, pid, sendSig)
sRattle("scr.d." .. ma, d) sRattle("scr.d." .. ma, d)
pcall(saveSettings) pcall(saveSettings)
end, end,
forceRescan = rescanDevs forceRescan = rescanDevs,
-- NOTE: "pub." prefixed version of functions in sys.manage
getSetting = function (name)
if type(name) ~= "string" then error("Setting name must be string") end
return settings["pub." .. name]
end,
delSetting = function (name)
if type(name) ~= "string" then error("Setting name must be string") end
local val = nil
if name == "clipboard" then val = "" end
settings["pub." .. name] = val
sRattle("pub." .. name, val)
pcall(saveSettings)
end,
setSetting = function (name, val)
if type(name) ~= "string" then error("Setting name must be string") end
if type(val) ~= "string" then error("Setting value must be string") end
settings["pub." .. name] = val
sRattle("pub." .. name, val)
pcall(saveSettings)
end
} }
end) end)

View File

@ -109,6 +109,20 @@ return {
"apps/app-textedit.lua" "apps/app-textedit.lua"
}, },
}, },
["app-flash"] = {
desc = "KittenOS NEO EEPROM Flasher",
v = 0,
app = "app-flash",
deps = {
"neo"
},
dirs = {
"apps"
},
files = {
"apps/app-flash.lua"
},
},
["app-pass"] = { ["app-pass"] = {
desc = "KittenOS NEO Password Setter & Logout", desc = "KittenOS NEO Password Setter & Logout",
v = 0, v = 0,

View File

@ -88,127 +88,6 @@ function unicode.undoSafeTextFormat(s)
return res return res
end end
-- Yes, this is what I used the freed up SR space for.
-- Think of this as my apology for refusing translation support on NEO.
keymaps = {
-- 'synth' keymap
["unknown"] = {
},
["??-qwerty"] = {
{16, "QWERTYUIOP"},
{16, "qwertyuiop"},
{30, "ASDFGHJKL"},
{30, "asdfghjkl"},
{44, "ZXCVBNM"},
{44, "zxcvbnm"},
},
["??-qwertz"] = {
{16, "QWERTZUIOP"},
{16, "qwertzuiop"},
{30, "ASDFGHJKL"},
{30, "asdfghjkl"},
{44, "YXCVBNM"},
{44, "yxcvbnm"},
},
["??-dvorak"] = {
{19, "PYFGCRL"},
{19, "pyfgcrl"},
{30, "AOEUIDHTNS"},
{30, "aoeuidhtns"},
{45, "QJKXBMWVZ"},
{45, "qjkxbmwvz"},
},
}
for k, v in pairs(keymaps) do
for k2, v2 in ipairs(v) do
for i = 1, unicode.len(v2[2]) do
v[unicode.sub(v2[2], i, i)] = i + v2[1] - 1
end
v2[k2] = nil
end
end
currentKeymap = "unknown"
-- Not really part of this package, but...
unicode.getKeymap = function ()
return currentKeymap
end
-- raw info functions, they return nil if they don't know
-- Due to a fantastic oversight, unicode.byte or such doesn't exist in OCEmu,
-- so things are managed via "Ch" internally.
unicode.getKCByCh = function (ch, km)
return keymaps[km][ch]
end
unicode.getChByKC = function (kc, km)
for ach, akc in pairs(keymaps[km]) do
if akc == kc then
return ach
end
end
end
local function keymapDetect(ka, kc)
if ka == 0 then return end
if kc == 0 then return end
-- simple algorithm, does the job
-- emergencyFunction("KD: " .. unicode.char(signal[3]) .. " " .. signal[4])
ka = unicode.char(ka)
if keymaps["unknown"][ka] ~= kc then
keymaps["unknown"][ka] = kc
else
return
end
-- 25% of used keys must be known to pass
local bestRatio = 0.25
local bestName = "unknown"
for k, _ in pairs(keymaps) do
if k ~= "unknown" then
local count = 0
local total = 0
for kCh, kc in pairs(keymaps["unknown"]) do
if unicode.getKCByCh(kCh, k) == kc then
count = count + 1
end
total = total + 1
end
local r = count / math.max(1, total)
if r > bestRatio then
bestRatio = r
bestName = k
end
end
end
if currentKeymap ~= bestName then emergencyFunction("Switching to Keymap " .. bestName) end
currentKeymap = bestName
end
-- rtext, codes (codes can end up nil)
-- rtext is text's letters switched over
-- (for code that will still use the same keycodes,
-- but wants to display correct text)
-- codes is the keycodes mapped based on the letters
unicode.keymap = function (text)
local km = unicode.getKeymap()
local rtext = ""
local codes = {}
local notQ = false
for i = 1, unicode.len(text) do
local ch = unicode.sub(text, i, i)
local okc = unicode.getKCByCh(ch, "??-qwerty") or 0
local ch2 = unicode.getChByKC(okc, currentKeymap) or unicode.getChByKC(okc, "unknown")
if not ch2 then
ch2 = "?"
else
notQ = true
end
rtext = rtext .. ch2
codes[i] = unicode.getKCByCh(ch, currentKeymap) or unicode.getKCByCh(ch, "unknown")
end
if not notQ then
rtext = text
end
return rtext, codes
end
local function loadfile(s, e) local function loadfile(s, e)
local h = primaryDisk.open(s) local h = primaryDisk.open(s)
if h then if h then
@ -714,52 +593,48 @@ end
if not start("sys-init") then error("Could not start sys-init") end if not start("sys-init") then error("Could not start sys-init") end
while true do while true do
local tmr = nil local ok, r = pcall(function()
for i = 1, 16 do local tmr = nil
tmr = nil for i = 1, 16 do
local now = computer.uptime() tmr = nil
local breaking = false -- Used when a process dies - in this case it's assumed OC just did something drastic local now = computer.uptime()
local didAnything = false local breaking = false -- Used when a process dies - in this case it's assumed OC just did something drastic
local k = 1 local didAnything = false
while timers[k] do local k = 1
local v = timers[k] while timers[k] do
if v[1] <= now then local v = timers[k]
if v[2](table.unpack(v, 3)) then if v[1] <= now then
breaking = true table.remove(timers, k)
tmr = 0.05 if v[2](table.unpack(v, 3)) then
break breaking = true
end tmr = 0.05
didAnything = true break
v = nil end
else didAnything = true
if not tmr then
tmr = v[1]
else else
tmr = math.min(tmr, v[1]) if not tmr then
tmr = v[1]
else
tmr = math.min(tmr, v[1])
end
k = k + 1
end end
end end
if v then if breaking then break end
k = k + 1 -- If the system didn't make any progress, then we're waiting for a signal (this includes timers)
else if not didAnything then break end
table.remove(timers, k)
end
end end
if breaking then break end now = computer.uptime() -- the above probably took a while
-- If the system didn't make any progress, then we're waiting for a signal (this includes timers) local dist = nil
if not didAnything then break end if tmr then
end dist = tmr - now
now = computer.uptime() -- the above probably took a while if dist < 0.05 then dist = 0.05 end
local dist = nil end
if tmr then local signal = {computer.pullSignal(dist)}
dist = tmr - now idleTime = idleTime + (computer.uptime() - now)
if dist < 0.05 then dist = 0.05 end if signal[1] then
end distEvent(nil, "h." .. signal[1], select(2, table.unpack(signal)))
local signal = {computer.pullSignal(dist)} end
if signal[1] == "key_down" then end)
keymapDetect(signal[3], signal[4]) if not ok then emergencyFunction("K-WARN " .. tostring(r)) end
end
idleTime = idleTime + (computer.uptime() - now)
if signal[1] then
distEvent(nil, "h." .. signal[1], select(2, table.unpack(signal)))
end
end end