global refactoring
This commit is contained in:
parent
1b55bb0ba6
commit
0812075336
36 changed files with 209 additions and 742 deletions
91
A/ccp.lua
Normal file
91
A/ccp.lua
Normal file
|
@ -0,0 +1,91 @@
|
|||
return function(argv, con)
|
||||
|
||||
local runs = true
|
||||
|
||||
local function parseArgs(ln)
|
||||
local iq, buf, args = false, '', {}
|
||||
local qt, esc = nil, false
|
||||
|
||||
-- helper function
|
||||
local function psh()
|
||||
if #buf > 0 then table.insert(args, buf) end
|
||||
buf, qt = '', nil
|
||||
end
|
||||
|
||||
for i = 1, #ln + 1 do
|
||||
local v = ln:sub(i, i)
|
||||
if ((v == ' ' or v == '\n' or v == '\t') and not iq)
|
||||
or v == ''
|
||||
then psh()
|
||||
|
||||
elseif esc then esc, buf = false, buf.. v
|
||||
elseif v == '\\' then esc = true
|
||||
|
||||
elseif (not qt or qt == v)
|
||||
and (v == '"' or v == "'")
|
||||
then psh()
|
||||
qt, iq = v, not iq
|
||||
|
||||
else buf = buf.. v
|
||||
end
|
||||
end
|
||||
|
||||
return args
|
||||
end
|
||||
|
||||
local cd = 'A:'
|
||||
|
||||
await(function()
|
||||
con.print(cd.. '>')
|
||||
con.down()
|
||||
local ln = con.getln()
|
||||
local argv = parseArgs(ln)
|
||||
|
||||
if not argv[1] then -- nothing
|
||||
|
||||
elseif argv[1]:lower() == 'dir' then
|
||||
local cp, f = 0, fsLs(cd)
|
||||
for _, v in pairs(f) do
|
||||
if cp + 14 + #cd >= con.w
|
||||
then con.print '\n'; cp = 0 end
|
||||
if cp == 0 then cp = #cd
|
||||
con.print(cd)
|
||||
else con.print ' : ' end
|
||||
local i = fsInfo(cd..v)
|
||||
local n, ext = v:match('(.+)%.(.+)$')
|
||||
n = n or v
|
||||
if #n > 8
|
||||
then con.print(n:sub(1, 6) .. '~1')
|
||||
elseif #n < 8
|
||||
then con.print(n ..(' '):rep(8 - #n))
|
||||
end
|
||||
con.print ' '
|
||||
if i.type == 'directory' then con.print '<D>'
|
||||
elseif i.type == 'symlink' then con.print '<S>'
|
||||
elseif i.type == 'other' then con.print '<O>'
|
||||
elseif ext then
|
||||
con.print(ext:upper():sub(1, 3))
|
||||
con.print((' '):rep(3 - #ext))
|
||||
else con.print ' '
|
||||
end
|
||||
cp = cp + 14
|
||||
end
|
||||
con.print '\n'
|
||||
|
||||
elseif argv[1]:match '%u:' then
|
||||
cd = argv[1]
|
||||
|
||||
elseif argv[1]:lower() == 'type' then
|
||||
con.print(fsRead(argv[2]))
|
||||
con.print '\n'
|
||||
|
||||
else con.println(argv[1].. ': command not found')
|
||||
|
||||
end
|
||||
|
||||
return not runs
|
||||
end)
|
||||
|
||||
return sh
|
||||
|
||||
end
|
8
A/ver.lua
Normal file
8
A/ver.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
return function(argv, con)
|
||||
con.print('Er2/L '.. VER)
|
||||
con.print(' On the Love2D '.. table.concat({love.getVersion()}, '.', 1, 3))
|
||||
con.println(' 20 FEB 22')
|
||||
local txt = ('Terminal size is %dx%d characters'):format(con.w, con.h)
|
||||
local sp = (' '):rep((con.w - #txt) / 2)
|
||||
con.println(sp.. txt ..'\n\n\n')
|
||||
end
|
|
@ -5,4 +5,4 @@
|
|||
-- Load default shell
|
||||
|
||||
loadapp 'ver'
|
||||
loadapp 'ersh'
|
||||
loadapp 'ccp'
|
||||
|
|
1
main.lua
1
main.lua
|
@ -5,4 +5,5 @@ require 'src.os' (con)
|
|||
|
||||
require 'autoexec'
|
||||
|
||||
con.getch()
|
||||
love.event.push 'quit'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
ACTIVE = true
|
||||
function __run()
|
||||
function __run(debug)
|
||||
if love.event then
|
||||
love.event.pump()
|
||||
for n, a,b,c,d,e,f in love.event.poll() do
|
||||
|
@ -23,10 +23,11 @@ function __run()
|
|||
if love.graphics and love.graphics.isActive() then
|
||||
love.graphics.origin()
|
||||
love.graphics.clear(0, 0, 0)
|
||||
--if debug then love.graphics.rectangle('fill', 0,0, 10, 10) end
|
||||
if love.draw then love.draw() end
|
||||
love.graphics.present()
|
||||
end
|
||||
if love.timer then love.timer.sleep(0.001) end
|
||||
--if love.timer then love.timer.sleep(0.001) end
|
||||
end
|
||||
|
||||
function await(fn)
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
return function(con)
|
||||
|
||||
local sh = {
|
||||
prompt = function() return '>' end,
|
||||
runs = true,
|
||||
env = {
|
||||
code = 0,
|
||||
path = 'sysapps:apps',
|
||||
}
|
||||
}
|
||||
|
||||
function sh:which(cmd)
|
||||
local file = cmd or ''
|
||||
if file:sub(-4) ~= '.lua'
|
||||
then file = file.. '.lua'
|
||||
end
|
||||
if fsHas(file)
|
||||
then return '', file end
|
||||
for path in self.env.path:gmatch '[^:]+' do
|
||||
if fsHas(path..'/'..file)
|
||||
then return path, '/'..file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function sh:parseArgs(ln)
|
||||
local iq, buf, args = false, '', {}
|
||||
local qt, esc = nil, false
|
||||
|
||||
ln = ln:gsub('%$(%S+)%s*=%s*(.*)$', function(k, v)
|
||||
env[k] = self:parseArgs(v)[1]
|
||||
return ''
|
||||
end)
|
||||
|
||||
-- helper function
|
||||
local function psh()
|
||||
if buf:sub(1,1) == '$'
|
||||
then buf = tostring(self.env[buf:sub(2)] or '') end
|
||||
if #buf > 0 then table.insert(args, buf) end
|
||||
buf, qt = '', nil
|
||||
end
|
||||
|
||||
for i = 1, #ln + 1 do
|
||||
local v = ln:sub(i, i)
|
||||
if ((v == ' ' or v == '\n' or v == '\t') and not iq)
|
||||
or v == ''
|
||||
then psh()
|
||||
|
||||
elseif esc then esc, buf = false, buf.. v
|
||||
elseif v == '\\' then esc = true
|
||||
|
||||
elseif (not qt or qt == v)
|
||||
and (v == '"' or v == "'")
|
||||
then psh()
|
||||
qt, iq = v, not iq
|
||||
|
||||
else buf = buf.. v
|
||||
end
|
||||
end
|
||||
|
||||
return args
|
||||
end
|
||||
|
||||
function sh:run()
|
||||
return 'TODO'
|
||||
end
|
||||
|
||||
function sh:loop()
|
||||
await(function()
|
||||
con.print(self:prompt())
|
||||
local ln = con.getln()
|
||||
con.down()
|
||||
|
||||
local res = self:run(ln)
|
||||
if res then con.println(res) end
|
||||
|
||||
return not self.runs
|
||||
end)
|
||||
end
|
||||
|
||||
return sh
|
||||
|
||||
end
|
31
src/draw.lua
31
src/draw.lua
|
@ -1,31 +0,0 @@
|
|||
-- Drawing API
|
||||
--- (c) Er2 2021-2022
|
||||
--- Zlib License
|
||||
|
||||
local comp = {
|
||||
'system', 'transform',
|
||||
'color', 'figures', 'font',
|
||||
'line', 'picture', 'rcorn',
|
||||
'rrect',
|
||||
}
|
||||
|
||||
FILL, LINE = 1, 0
|
||||
|
||||
local draw = {}
|
||||
draw.__index = draw
|
||||
|
||||
function draw.new(w, h)
|
||||
assert(w > 0 and h > 0, 'cr must be greater than 0')
|
||||
local cr = setmetatable({}, draw)
|
||||
cr._cr = love.graphics.newCanvas(w, h)
|
||||
cr.w, cr.h = w, h
|
||||
cr:newFont()
|
||||
return cr
|
||||
end
|
||||
|
||||
for _, v in pairs(comp) do
|
||||
require('src.draw.'.. v)(draw)
|
||||
end
|
||||
|
||||
draw:newFont()
|
||||
return setmetatable({}, draw)
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
local f = (love.getVersion or
|
||||
function() return love._version_major
|
||||
end)() == 0 and 1 or 255
|
||||
|
||||
return function(draw)
|
||||
|
||||
function draw:color(r, g, b, a)
|
||||
a = a or 255
|
||||
love.graphics.setColor(r / f, g / f, b / f, a / f)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:colorT(t)
|
||||
return self:color(t[1], t[2], t[3], t[4])
|
||||
end
|
||||
|
||||
function draw:colorH(hex)
|
||||
hex = (tostring(hex) or ''):lower()
|
||||
local r, g, b, a = hex:match '#?(%x%x?)(%x%x?)(%x%x?)'
|
||||
r = #r == 1 and r..r or r
|
||||
g = #g == 1 and g..g or g
|
||||
b = #b == 1 and b..b or b
|
||||
if a then a = #a == 1 and a..a or a end
|
||||
return self:color(
|
||||
tonumber(r, 16), tonumber(g, 16),
|
||||
tonumber(b, 16),
|
||||
not a and 255 or tonumber(a, 16)
|
||||
)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
local function gm(m)
|
||||
return m == FILL and 'fill' or 'line'
|
||||
end
|
||||
|
||||
return function(draw)
|
||||
|
||||
function draw:rect(m, x, y, w, h)
|
||||
love.graphics.rectangle(gm(m), x, y, w, h)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:ellipse(m, x, y, rx, ry)
|
||||
love.graphics.ellipse(gm(m), x, y, rx, ry)
|
||||
if m == FILL then
|
||||
self:ellipse(LINE, x, y, rx, ry)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:circle(m, x, y, r)
|
||||
return self:ellipse(m, x, y, r, r)
|
||||
end
|
||||
|
||||
function draw:triang(m, x, y, ox1, oy1, ox2, oy2)
|
||||
if m == FILL then self:triang(LINE, x, y, ox1, oy1, ox2, oy2) end
|
||||
love.graphics.polygon(gm(m), x, y, x + ox1, y + oy1, x + ox2, y + oy2)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:arc(m, cx, cy, r, sa, ea)
|
||||
love.graphics.arc(gm(m), m == FILL and 'pie' or 'open',
|
||||
cx, cy, r, sa, ea)
|
||||
if m == FILL then self:arc(LINE, cx, cy, r, sa, ea) end
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:text(t, x, y)
|
||||
love.graphics.setFont(self.f)
|
||||
love.graphics.print(t, x, y)
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:font(f)
|
||||
if f then self.f = f end
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:newFont(...)
|
||||
return self:font(love.graphics.newFont(...))
|
||||
end
|
||||
|
||||
function draw:getFText(t)
|
||||
return self.f:getWidth(t), self.f:getHeight(t)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:lineWidth(w)
|
||||
love.graphics.setLineWidth(w)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:line(x1, y1, x2, y2)
|
||||
love.graphics.line(x1, y1, x2, y2)
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:img(im, x, y, r, sx, sy)
|
||||
love.graphics.draw(im, x, y, r, sx, sy)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:cr(cr, x, y, r, sx, sy)
|
||||
if cr.fr then return end
|
||||
return self:img(cr._cr, x, y, r, sx, sy)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:rcorn(x, y, d, p)
|
||||
p = p or 1
|
||||
if p == 1 then self -- bot-right
|
||||
|
||||
:arc(LINE, x - d, y - d, d, 0, math.pi / 2)
|
||||
:triang(FILL, x, y - d, 0, d, -d/2, d)
|
||||
:triang(FILL, x - d, y, d / 1.5, -d / 4, d, 0)
|
||||
|
||||
elseif p == 2 then self -- bot-left
|
||||
|
||||
:arc(LINE, x + d, y - d, d, math.pi / 2, math.pi)
|
||||
:triang(FILL, x, y - d, 0, d, d/2, d)
|
||||
:triang(FILL, x, y, d / 1.5, -d / 4, d, 0)
|
||||
|
||||
elseif p == 3 then self -- top-right
|
||||
|
||||
:arc(LINE, x - d, y + d, d, math.pi * 1.5, math.pi * 2)
|
||||
:triang(FILL, x, y, 0, d, -d/2, 0)
|
||||
:triang(FILL, x - d, y, d / 1.5, d / 4, d, 0)
|
||||
|
||||
elseif p == 4 then self -- top-left
|
||||
|
||||
:arc(LINE, x + d, y + d, d, math.pi, math.pi * 1.5)
|
||||
:triang(FILL, x, y, 0, d, d/2, 0)
|
||||
:triang(FILL, x, y, d / 1.5, d / 4, d, 0)
|
||||
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:rrect(m, x, y, w, h, r)
|
||||
local rtl, rtr, rbl, rbr = r[1] or 8, r[2], r[3], r[4]
|
||||
rtr = rtr or rtl
|
||||
rbl = rbl or rtl
|
||||
rbr = rbr or rbl
|
||||
|
||||
local ml, mr, Ml, Mr, Mt, Mb =
|
||||
math.min(rtl, rbl), math.min(rtr, rbr),
|
||||
math.max(rtl, rbl), math.max(rtr, rbr),
|
||||
math.max(rtl, rtr), math.max(rbl, rbr)
|
||||
if m == FILL then self
|
||||
:rect(m, x + Ml, y + Mt, w - Ml - Mr, h - Mt - Mb)
|
||||
:rect(m, x + rtl, y, w - rtl - rtr, Mt) -- top
|
||||
:rect(m, x + rbl, y + h - Mb, w - rbl - rbr, Mb) -- bottom
|
||||
:rect(m, x, y + rtl, Ml, h - rtl - rbl) -- left
|
||||
:rect(m, x + w - Mr, y + rtr, Mr, h - rtr - rbr) -- right
|
||||
end
|
||||
self
|
||||
:line(x + rtl, y, x + w - rtr, y)
|
||||
:line(x, y + rtl, x, y + h - rbl)
|
||||
:line(x + rbl, y + h, x + w - rbr, y + h)
|
||||
:line(x + w, y + rtr, x + w, y + h - rbr)
|
||||
|
||||
:arc(m, x + rtl, y + rtl, rtl, math.pi, math.pi * 1.5)
|
||||
:arc(m, x + w - rtr, y + rtr, rtr, math.pi * 1.5, math.pi * 2)
|
||||
:arc(m, x + w - rbr, y + h - rbr, rbr, 0, math.pi / 2)
|
||||
:arc(m, x + rbl, y + h - rbl, rbl, math.pi / 2, math.pi)
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
|
@ -1,36 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:free(f)
|
||||
if self.fr then return end
|
||||
self.fr = true
|
||||
--if self._cr then self._cr:release() end
|
||||
if f then draw:freeFont() end
|
||||
collectgarbage 'collect'
|
||||
end
|
||||
function draw:freeFont()
|
||||
if self.f then self.f:release() end
|
||||
end
|
||||
|
||||
function draw:give()
|
||||
if self.fr then return end
|
||||
self.pc = love.graphics.getCanvas()
|
||||
if self.pc ~= self.cr then
|
||||
love.graphics.push()
|
||||
love.graphics.origin()
|
||||
love.graphics.setCanvas(self._cr)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:back()
|
||||
love.graphics.setCanvas(self.pc)
|
||||
love.graphics.pop()
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:full(full)
|
||||
love.window.setFullscreen(full or false)
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
return function(draw)
|
||||
|
||||
function draw:orig()
|
||||
love.graphics.origin()
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:move(x, y)
|
||||
love.graphics.translate(x, y)
|
||||
return self
|
||||
end
|
||||
|
||||
function draw:scale(sx, sy)
|
||||
love.graphics.scale(sx, sy)
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
16
src/fs.lua
16
src/fs.lua
|
@ -2,17 +2,23 @@ return function()
|
|||
|
||||
local lfs = love.filesystem
|
||||
|
||||
function fsPath(path)
|
||||
local v = path:gsub(':', '/')
|
||||
return v
|
||||
end
|
||||
|
||||
function fsLs(path)
|
||||
return lfs.getDirectoryItems(path)
|
||||
return lfs.getDirectoryItems(fsPath(path))
|
||||
end
|
||||
|
||||
function fsHas(file)
|
||||
if lfs.getInfo
|
||||
then return not not lfs.getInfo(file) end
|
||||
return lfs.exists(file)
|
||||
then return not not lfs.getInfo(fsPath(file)) end
|
||||
return lfs.exists(fsPath(file))
|
||||
end
|
||||
|
||||
function fsInfo(file)
|
||||
file = fsPath(file)
|
||||
if lfs.getInfo
|
||||
then return lfs.getInfo(file)
|
||||
end
|
||||
|
@ -28,4 +34,8 @@ function fsInfo(file)
|
|||
return info
|
||||
end
|
||||
|
||||
function fsRead(file)
|
||||
return lfs.read(fsPath(file)), nil
|
||||
end
|
||||
|
||||
end
|
||||
|
|
28
src/gui.lua
28
src/gui.lua
|
@ -1,28 +0,0 @@
|
|||
local nlv = {}
|
||||
for k, v in pairs(love) do
|
||||
nlv[k] = v
|
||||
end
|
||||
|
||||
local gui = {}
|
||||
|
||||
function gui.init()
|
||||
love.draw = gui.draw
|
||||
love.update = gui.update
|
||||
|
||||
love.keypressed = nil
|
||||
love.keyreleased = nil
|
||||
love.textedited = nil
|
||||
love.textinput = nil
|
||||
end
|
||||
|
||||
function gui.update(dt)
|
||||
updM()
|
||||
end
|
||||
|
||||
function gui.stop()
|
||||
for k, v in pairs(nlv) do
|
||||
love[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return gui
|
BIN
src/hack.ttf
BIN
src/hack.ttf
Binary file not shown.
BIN
src/hack.ttf.old
Normal file
BIN
src/hack.ttf.old
Normal file
Binary file not shown.
19
src/os.lua
19
src/os.lua
|
@ -7,15 +7,14 @@ love.keyboard.setKeyRepeat(true)
|
|||
require 'src.mouse' (con)
|
||||
require 'src.fs' ()
|
||||
require 'src.async'
|
||||
draw = require 'src.draw'
|
||||
|
||||
local w, h
|
||||
local w, h, f
|
||||
function love.resize(x, y)
|
||||
w, h = math.max(32, x), math.max(32, y)
|
||||
draw:newFont('src/hack.ttf', math.min(w, h) / 32)
|
||||
local cw, ch = draw:getFText 'A'
|
||||
f = love.graphics.setNewFont('src/hack.ttf', math.min(w, h) / 32)
|
||||
local cw, ch = f:getWidth 'A', f:getHeight 'A'
|
||||
collectgarbage 'collect'
|
||||
con:emit('res', w, h, cw, ch)
|
||||
con.resz(w, h, cw, ch)
|
||||
end
|
||||
love.resize(love.graphics.getDimensions())
|
||||
love.window.setMode(w, h, {
|
||||
|
@ -27,23 +26,25 @@ love.window.setMode(w, h, {
|
|||
love.textinput = con.type
|
||||
love.keypressed = con.keydown
|
||||
|
||||
local sf = (love.getVersion() or love._version_major)
|
||||
== 0 and 1 or 255
|
||||
|
||||
function love.draw()
|
||||
draw:color(100, 255, 0)
|
||||
love.graphics.setColor(100 / sf, 255 / sf, 0)
|
||||
con.forText(function(l, x, y)
|
||||
local cw, ch = draw:getFText(l)
|
||||
if not (
|
||||
l == '\n'
|
||||
or l == '\r'
|
||||
or l == '\v'
|
||||
or l == '\t'
|
||||
)
|
||||
then draw:text(l, x * con.cw + (con.cw - cw) / 2, y * con.ch + con.oy)
|
||||
then love.graphics.print(l, x * con.cw, y * con.ch + con.oy)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function loadapp(name, ...)
|
||||
local succ, msg = pcall(require, 'sysapps.'.. name)
|
||||
local succ, msg = pcall(require, 'A.'.. name)
|
||||
if not succ then
|
||||
con.println('ERROR: '.. msg)
|
||||
print(msg)
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
--[[ Events library
|
||||
-- (c) Er2 2021 <er2@dismail.de>
|
||||
-- Zlib License
|
||||
--]]
|
||||
|
||||
local events = {}
|
||||
events.__index = events
|
||||
|
||||
function events:_add(t, n, f)
|
||||
table.insert(self._ev_, {
|
||||
type = t,
|
||||
name = n,
|
||||
fn = f,
|
||||
})
|
||||
end
|
||||
|
||||
function events:on(n,f) self:_add('on', n,f) end
|
||||
function events:once(n,f) self:_add('once', n,f) end
|
||||
|
||||
function events:off(f)
|
||||
for k, v in pairs(self._ev_) do
|
||||
if v.fn == f then
|
||||
table.remove(self._ev_, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function events:_ev(t, i, name, ...)
|
||||
local v = t[i]
|
||||
if v.name == name then
|
||||
v.fn(...)
|
||||
if v.type == 'once' then table.remove(t, i) end
|
||||
end
|
||||
end
|
||||
|
||||
function events:emit(name, ...)
|
||||
local t = self._ev_
|
||||
for i = 1, #t do
|
||||
local v = t[i] or {}
|
||||
if type(v) == 'table'
|
||||
and type(v.name) == 'string'
|
||||
and type(v.type) == 'string'
|
||||
and type(v.fn) == 'function'
|
||||
then self:_ev(t, i, name, ...) end
|
||||
end
|
||||
end
|
||||
|
||||
return function(t)
|
||||
t._ev_ = {}
|
||||
return setmetatable(t, events)
|
||||
end
|
|
@ -1,43 +1,31 @@
|
|||
return function(con)
|
||||
|
||||
-- KostylLand
|
||||
--- Special for (almost) terminal
|
||||
--- (c) Er2 2022 <er2@dismail.de>
|
||||
|
||||
local function updK()
|
||||
__run(true)
|
||||
end
|
||||
|
||||
function con.getch(tout)
|
||||
local t, ch = os.time(), nil
|
||||
con.usebs = false
|
||||
con:once('type', function(text)
|
||||
ch = text:sub(1, 1)
|
||||
end)
|
||||
await(function() return
|
||||
ch ~= nil
|
||||
or (tout and os.time() - t >= tout)
|
||||
end)
|
||||
con.usebs = true
|
||||
return ch
|
||||
while ch == nil and ACTIVE do
|
||||
updK()
|
||||
ch = con.popbuf(false)
|
||||
if tout and os.time() - t >= tout
|
||||
then break end
|
||||
end
|
||||
return ch or ''
|
||||
end
|
||||
|
||||
function con.getln()
|
||||
local ln, du = '', true
|
||||
local function _ln(text)
|
||||
ln = ln .. text
|
||||
local ln
|
||||
while ln == nil and ACTIVE do
|
||||
updK()
|
||||
ln = con.popbuf(true)
|
||||
end
|
||||
local function _dwn(k)
|
||||
if k == 'backspace' then
|
||||
if #ln == 0 then con.usebs = false
|
||||
else
|
||||
con.usebs = true
|
||||
ln = con.bs(ln)
|
||||
end
|
||||
end
|
||||
end
|
||||
con:on('type', _ln)
|
||||
con:on('down', _dwn)
|
||||
con:once('return', function()
|
||||
con:off(_ln)
|
||||
con:off(_dwn)
|
||||
con.usebs = true
|
||||
du = false
|
||||
end)
|
||||
await(function() return not du end)
|
||||
return ln
|
||||
return ln or ''
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,15 +2,13 @@ utf8 = require 'utf8'
|
|||
|
||||
-- Model
|
||||
local con = {
|
||||
text = {''},
|
||||
out = {''},
|
||||
w = 0, h = 0,
|
||||
cw = 0, ch = 0,
|
||||
oy = 0, th = 0,
|
||||
usebs = true,
|
||||
}
|
||||
|
||||
local m = {
|
||||
'events', -- REQUIRED!
|
||||
'loop',
|
||||
'resize', 'type', 'get',
|
||||
}
|
||||
|
@ -19,6 +17,4 @@ for _, v in pairs(m) do
|
|||
require('src.term.'.. v)(con)
|
||||
end
|
||||
|
||||
con:emit('init')
|
||||
|
||||
return con
|
||||
|
|
|
@ -2,7 +2,7 @@ return function(con)
|
|||
|
||||
function con.forLine(l, fn, oy)
|
||||
local x, y = 0, 0
|
||||
for j, l in utf8.codes(con.text[l]) do
|
||||
for j, l in utf8.codes(con.out[l]) do
|
||||
l = utf8.char(l)
|
||||
if fn then fn(l, x, y + oy) end
|
||||
if l == '\t' then x = x + 8 - (x % 8)
|
||||
|
@ -10,15 +10,13 @@ function con.forLine(l, fn, oy)
|
|||
elseif l == '\r' then x = 0
|
||||
else x = x + 1
|
||||
end
|
||||
if x + 1 > con.w
|
||||
then x, y = 0, y + 1 end
|
||||
end
|
||||
return y
|
||||
end
|
||||
|
||||
function con.forText(fn)
|
||||
local y = 0
|
||||
for i = 1, #con.text do
|
||||
for i = 1, #con.out do
|
||||
y = y + 1 + con.forLine(i, fn, y)
|
||||
end
|
||||
return y
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
return function(con)
|
||||
|
||||
con:on('res', function(w, h, cw, ch)
|
||||
con.cw, con.ch = cw or con.cw, ch or con.ch
|
||||
function con.resz(w, h, cw, ch)
|
||||
con.cw, con.ch =
|
||||
cw or con.cw,
|
||||
ch or con.ch
|
||||
con.w, con.h =
|
||||
math.floor(w / cw),
|
||||
math.floor(h / ch)
|
||||
con:emit('resT')
|
||||
end)
|
||||
con.reszT()
|
||||
end
|
||||
|
||||
con:on('resT', function()
|
||||
function con.reszT()
|
||||
local y = con.forText()
|
||||
con.th = y * con.ch
|
||||
end)
|
||||
end
|
||||
|
||||
function con.down()
|
||||
con.oy = 0
|
||||
|
|
|
@ -1,28 +1,59 @@
|
|||
return function(con)
|
||||
|
||||
function con.curln(of)
|
||||
return con.text[#con.text - (of or 0)]
|
||||
local buf = {''}
|
||||
|
||||
function con.keydown(k)
|
||||
if k == 'backspace' then
|
||||
if #buf[#buf] > 0 then con.bs() end
|
||||
elseif k == 'return' then
|
||||
con.type '\n'
|
||||
table.insert(buf, '')
|
||||
end
|
||||
end
|
||||
|
||||
function con.setln(v, of)
|
||||
con.text[#con.text - (of or 0)] = tostring(v)
|
||||
return v
|
||||
function con.popbuf(line)
|
||||
local v = buf[#buf-1] or ''
|
||||
if line then
|
||||
if v:sub(-1) == '\n' then
|
||||
buf[#buf-1] = ''
|
||||
return v:sub(1, -2)
|
||||
end
|
||||
else
|
||||
buf[#buf] = bs(buf[#buf])
|
||||
v = v:sub(1,1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function con.bs(oth)
|
||||
if not con.usebs then return end
|
||||
local s = oth or con.curln()
|
||||
local off = utf8.offset(s, -1)
|
||||
if off then
|
||||
s = s:sub(1, off - 1)
|
||||
function con.type(text)
|
||||
buf[#buf] = buf[#buf].. text
|
||||
con.print(text)
|
||||
end
|
||||
if not oth then con.setln(s) end
|
||||
return s
|
||||
|
||||
local function bs(v)
|
||||
local off = utf8.offset(v, -1)
|
||||
if off then v = v:sub(1, off - 1) end
|
||||
return v, off ~= nil
|
||||
end
|
||||
|
||||
function con.bs()
|
||||
buf[#buf] = bs(buf[#buf])
|
||||
con.out[#con.out] = bs(con.out[#con.out])
|
||||
end
|
||||
|
||||
function con.cls()
|
||||
buf = {''}
|
||||
con.text = {''}
|
||||
con.oy = 0
|
||||
con.reszT()
|
||||
end
|
||||
|
||||
function con.ret()
|
||||
table.insert(con.out, '')
|
||||
end
|
||||
|
||||
local function conc(a, b)
|
||||
return tostring(a)..tostring(b)
|
||||
end
|
||||
|
||||
function con.print(text)
|
||||
|
@ -30,38 +61,15 @@ function con.print(text)
|
|||
v = utf8.char(v)
|
||||
if v == '\n' then con.ret()
|
||||
elseif v == '\b' then con.bs()
|
||||
-- \r\t\v is in loop
|
||||
else con.puts(v)
|
||||
-- \r\t\v is in loop.lua
|
||||
else con.out[#con.out] = conc(con.out[#con.out],v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function con.puts(text)
|
||||
con.setln(con.curln().. text)
|
||||
con:emit('resT')
|
||||
con.reszT()
|
||||
end
|
||||
|
||||
function con.println(text)
|
||||
con.print(tostring(text).. '\n')
|
||||
end
|
||||
|
||||
function con.ret()
|
||||
table.insert(con.text, '')
|
||||
end
|
||||
|
||||
function con.type(text)
|
||||
con.puts(text)
|
||||
con:emit('type', text)
|
||||
end
|
||||
|
||||
function con.keydown(k)
|
||||
con:emit('down', k)
|
||||
if k == 'backspace' then con.bs()
|
||||
elseif k == 'return' then
|
||||
con.ret()
|
||||
con.down()
|
||||
con:emit('return')
|
||||
end
|
||||
con.print(conc(text,'\n'))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
54
src/win.lua
54
src/win.lua
|
@ -1,54 +0,0 @@
|
|||
local gui = require 'src.gui'
|
||||
|
||||
local wins = {
|
||||
{x = 64, y = 64, w = 64, h = 64},
|
||||
}
|
||||
|
||||
local bw, th = 8, 16
|
||||
|
||||
function gui.draw()
|
||||
draw:color(0, 100, 150)
|
||||
:rect(FILL, 0, 0, gui.w, gui.h)
|
||||
:color(255, 255, 255)
|
||||
:text('This is a demo of GUI in ErDOS', gui.w / 4, gui.h / 2)
|
||||
for i = #wins, 1, -1 do
|
||||
local v = wins[i]
|
||||
draw
|
||||
:color(100, 100, 100)
|
||||
:rrect(FILL,
|
||||
v.x - bw, v.y - bw - th,
|
||||
v.w + bw * 2, v.h + bw * 2 + th,
|
||||
{bw}
|
||||
)
|
||||
:color(255, 255, 255)
|
||||
:rect(FILL, v.x, v.y, v.w, v.h)
|
||||
end
|
||||
end
|
||||
|
||||
function AABB(x1, y1, w1, h1, x2, y2, w2, h2)
|
||||
return
|
||||
x1 + w1 > x2
|
||||
and x2 + w2 > x1
|
||||
and y1 + h1 > y2
|
||||
and y2 + h2 > y1
|
||||
end
|
||||
|
||||
function gui.update(dt)
|
||||
updM()
|
||||
for i = 1, #wins do
|
||||
local v = wins[i]
|
||||
if AABB(m.x, m.y, 0, 0,
|
||||
v.x - bw, v.y - bw - th,
|
||||
v.w + bw * 2, v.h + bw * 2 + th
|
||||
) then
|
||||
gui.stop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return function(w, h)
|
||||
gui.init()
|
||||
gui.w, gui.h =
|
||||
w or gui.w or 0,
|
||||
h or gui.h or 0
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
return function(argv, con)
|
||||
-- /Ckeys /S text
|
||||
local ch = {'Y', 'N'}
|
||||
local cs = false
|
||||
local i = 2
|
||||
while argv[i] do
|
||||
local v = argv[i]:upper()
|
||||
if v:sub(1,1) == '/'
|
||||
then table.remove(argv, i)
|
||||
else i = i + 1
|
||||
end
|
||||
if v:sub(1, 2) == '/C'
|
||||
and #v > 2 then
|
||||
ch = {}
|
||||
for l in v:sub(3):gmatch '.' do table.insert(ch, l) end
|
||||
elseif v == '/S' then cs = true
|
||||
end
|
||||
end
|
||||
con.print(table.concat(argv, ' ', 2))
|
||||
con.print(' ['.. table.concat(ch, ',') ..'] ')
|
||||
con.print('('.. ch[1] ..') ')
|
||||
local chr = con.getch(10)
|
||||
if not chr then chr = ch[1] end
|
||||
|
||||
local ret = 0
|
||||
for k, v in pairs(ch) do
|
||||
if v == chr
|
||||
or (not cs and v:upper() == chr:upper())
|
||||
then ret = k end
|
||||
end
|
||||
|
||||
con.print '\n'
|
||||
|
||||
return ret
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
return function(argv, con)
|
||||
con.cls()
|
||||
end
|
|
@ -1,31 +0,0 @@
|
|||
return function(argv, con)
|
||||
local dir = argv[2] or ''
|
||||
con.print(' Listing of '..dir ..'\n\n')
|
||||
local d = fsLs(dir)
|
||||
local dirs, files, tb = 0, 0, 0
|
||||
for _, v in pairs(d) do
|
||||
local i = fsInfo(dir..'/'..v)
|
||||
con.print(os.date('%m/%d/%Y %I:%M %p ', i.modtime))
|
||||
if i.type == 'directory' then con.print '<DIR>'
|
||||
elseif i.type == 'symlink' then con.print '<SYM>'
|
||||
elseif i.type == 'other' then con.print '<OTH>'
|
||||
else con.print ' ' end
|
||||
if i.type == 'directory' then
|
||||
dirs = dirs + 1
|
||||
con.print ' '
|
||||
else
|
||||
files = files + 1
|
||||
tb = tb + i.size
|
||||
con.print ' '
|
||||
local s = tostring(i.size)
|
||||
con.print((' '):rep(7 - #s))
|
||||
con.print(s)
|
||||
con.print ' '
|
||||
end
|
||||
|
||||
con.println(v)
|
||||
end
|
||||
con.println(('%d File(s)\n%d Dir(s)\n%d Bytes total')
|
||||
:format(files, dirs, tb))
|
||||
con.print '\n'
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
return function(argv, con)
|
||||
con.println(table.concat(argv, ' ', 2))
|
||||
end
|
|
@ -1,65 +0,0 @@
|
|||
return function(argv, con)
|
||||
|
||||
if argv[2] == '-v'
|
||||
then
|
||||
con.println 'Er2Shell 0.5'
|
||||
return
|
||||
end
|
||||
|
||||
local sh = require 'src.baseshell' (con)
|
||||
|
||||
function sh:prompt()
|
||||
return ('%d > '):format(self.env.code)
|
||||
end
|
||||
|
||||
function sh:run(ln)
|
||||
local argv = self:parseArgs(ln)
|
||||
|
||||
if not argv[1] then -- nothing
|
||||
|
||||
elseif argv[1] == 'exit' then
|
||||
self.runs = false
|
||||
|
||||
elseif argv[1] == 'which' then
|
||||
local fnd, snd = self:which(argv[2])
|
||||
if not fnd then self.env.code = 1
|
||||
else self.env.code = 0
|
||||
return fnd..snd
|
||||
end
|
||||
|
||||
elseif argv[1] == 'env' then
|
||||
local ls = ''
|
||||
for k, v in pairs(self.env) do
|
||||
k, v = tostring(k), tostring(v)
|
||||
ls=ls.. ('$%s=%s\n')
|
||||
:format(k, v:match '%s' and '"'..v..'"' or v)
|
||||
end
|
||||
self.env.code = 0
|
||||
return ls:sub(1, -2)
|
||||
|
||||
else
|
||||
local fnd, snd = self:which(argv[1])
|
||||
if not fnd then
|
||||
self.env.code = 127
|
||||
return argv[1].. ': command not found'
|
||||
else self.env.code = 0
|
||||
local succ, msg = pcall(select(2, pcall(loadfile, fnd..snd)))
|
||||
if not succ then
|
||||
print(msg)
|
||||
self.env.code = 126
|
||||
return argv[1].. ': file error'
|
||||
else
|
||||
local succ, msg = pcall(msg, argv, con, self.env)
|
||||
if not succ then
|
||||
self.env.code = self.env.code ~= 0 and self.env.code or 1
|
||||
return argv[1].. ': '.. tostring(msg)
|
||||
else self.env.code = tonumber(msg) or 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sh:loop()
|
||||
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
return function(argv, con)
|
||||
local pr = print
|
||||
print = con.println
|
||||
local suc, ret = pcall(load(table.concat(argv, ' ', 2)))
|
||||
print(ret)
|
||||
print = pr
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
return function(argv, con)
|
||||
con.println('ErDOS version '.. VER)
|
||||
con.println('Runs on\vLove2D '.. table.concat({love.getVersion()}, '.', 1, 3))
|
||||
con.println('(c) Er2 2022\tZlib License\n')
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
return function(argv, con)
|
||||
require 'src.win' (con.w * con.cw, con.h * con.ch)
|
||||
end
|
Loading…
Reference in a new issue