Skip to content

Commit

Permalink
red: voiced and sprited cmds, insert speedup, dump updated
Browse files Browse the repository at this point in the history
  • Loading branch information
hugeping committed Nov 17, 2023
1 parent 9cc3a6d commit 0d4c838
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 75 deletions.
92 changes: 79 additions & 13 deletions data/apps/red.lua
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ function mainmenu.cmd:Dump()
b.line = w.buf:line_nr()
b.text = w.buf:gettext()
b.menu = w.menu
b.cwd = w.cwd
end
c.menu = f:menu().buf:gettext()
table.insert(d, c)
Expand Down Expand Up @@ -1213,30 +1214,93 @@ local function resume()
sys.event_filter(oldevents)
end

function mainmenu.cmd:Run(t)
if not t then return end
function win:Run(cmd, ...)
prepare()
sys.exec(t)
sys.exec(cmd, ...)
sys.suspend()
-- resumed
resume()
end

function mainmenu.cmd:Run(t)
if not t then return end
self:Run(t)
end

function framemenu.cmd:Run(t)
local w = self.frame:win()
if not t and (not w or not w.buf:isfile()) then
return
end

if not t then
w:save()
end
self:Run(t or w.buf.fname)
end

prepare()
sys.exec(t or w.buf.fname)
sys.suspend()
-- resumed
resume(w)
local function select_sect(w, name)
local c = w:cur(1)
w:text_match(function(text)
local pat = string.format("local __%s__ = %%[%%[[^%%]]*%%]%%]", name)
return text:find(pat)
end)
w:cur(c)
local t = w.buf:getseltext()
local s, e
s, e, t = t:find("^[^%[]+%[%[(.*)%]%]$")
t = t and t:strip()
return t
end

local function input_sect(w, name, text)
if not text or text:empty() then return end
local old
select_sect(w, name)
local t = string.format("local __%s__ = [[\n%s\n]]", name, text)
if not w.buf:issel() then
old = w:cur()
w.buf.cur = #w.buf.text
w:input '\n'
end
w.buf:input(t)
if old then w:cur(old) end
end

function framemenu.cmd.voiced(w)
local data = w:winmenu()
if not data then return end
local fname = os.tmpname()
os.remove(fname)

local t = select_sect(data, "voices")
io.file(fname..'.syn', t or '')
t = select_sect(data, "songs")
io.file(fname..'.sng', t or '')

data:Run('voiced', fname..'.syn', fname..'.sng')

input_sect(data, "voices", io.file(fname..'.syn'))
input_sect(data, "songs", io.file(fname..'.sng'))

os.remove(fname..'.syn')
os.remove(fname..'.sng')
end

function framemenu.cmd.sprited(w)
local data = w:winmenu()
if not data then return end
local fname = os.tmpname()
os.remove(fname)

local t = select_sect(data, "spr")
io.file(fname..'.spr', t or '')
t = select_sect(data, "map")
io.file(fname..'.map', t or '')
data:Run('sprited', fname..'.spr')
input_sect(data, "spr", io.file(fname..'.spr'))
input_sect(data, "map", io.file(fname..'.map'))
os.remove(fname..'.spr')
os.remove(fname..'.map')
end

main:geom(0, 0, scr.w, scr.h)
Expand All @@ -1246,20 +1310,22 @@ local function load_dump(f)
if not d then return end
for i, v in ipairs(d) do
mainmenu.cmd.New(mainmenu) -- Newcol
local fr = main:win(i)
for _, b in ipairs(v) do
main:win(i):file(b.fname)
fr:file(b.fname)
if b.text then
local ww = main:win(i):win()
ww:set(b.text)
ww:dirty(ww.buf:dirty())
end
if b.line then
main:win(i):win():toline(b.line, false)
fr:win():toline(b.line, false)
end
main:win(i):win().menu = b.menu
fr:win().menu = b.menu
fr:win().cwd = b.cwd
end
if v.menu then
main:win(i):menu().buf:set(v.menu)
fr:menu().buf:set(v.menu)
end
end
if d.menu then
Expand Down
34 changes: 28 additions & 6 deletions data/lib/red/buf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ function buf:changed(fl)
return c
end

--local hist_delim = {
-- [" "] = true,
-- ["\n"] = true,
--}
--[[
local hist_delim = {
[" "] = true,
["\n"] = true,
}
]]--

function buf:history(op, pos, nr, append)
self:changed(true)
Expand Down Expand Up @@ -308,14 +310,34 @@ function buf:input(txt)
self:history('cut', self.cur, #u)
end
self:history('input', self.cur, #u)--, #u == 1 and not hist_delim[u[1]])
local txt = self.text
local rebuild
if #u > 512 and not over_mode then
rebuild = true
for i = 1, self.cur - 1 do
table.insert(txt, self.text[i])
end
txt = {}
end
local cur = self.cur
for i = 1, #u do
if over_mode then
self.text[self.cur] = u[i]
txt[self.cur] = u[i]
else
table.insert(self.text, self.cur, u[i])
if rebuild then
table.insert(txt, u[i])
else
table.insert(txt, self.cur, u[i])
end
end
self.cur = self.cur + 1
end
if rebuild then
for i = cur, #self.text do
table.insert(txt, self.text[i])
end
self.text = txt
end
if sel or over_mode then
self:history 'end'
end
Expand Down
60 changes: 4 additions & 56 deletions data/lib/red/proc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,6 @@ local shell = require "red/shell"

local proc = {}

local function cur_skip(text, pos)
local l = 1
local k = 0
while l < (pos or 1) do
local len = utf.next(text, l)
if len == 0 then
break
end
k = k + 1
l = l + len
end
return k
end

local function text_match(w, glob, fn, ...)
local s, e = w.buf.cur, #w.buf.text
local text = w.buf:gettext(s, e)
local start, fin = fn(text, ...)
if not start then
s, e = 1, w.buf.cur
text = w.buf:gettext(s, e)
start, fin = fn(text, ...)
end
if not start then
return
end
w.buf:resetsel()
w.buf.cur = s + cur_skip(text, start)
fin = s + cur_skip(text, fin + 1)
w.buf:setsel(w.buf.cur, fin)
w.buf.cur = fin
w:visible()
end

local function text_replace(w, glob, fn, a, b)
if a and (not w.buf:issel() or not b) then
return text_match(w, glob, fn, a)
end
local s, e = w.buf:range()
local text = w.buf:gettext(s, e)
text = fn(text, a, b)
w.buf:history 'start'
w.buf:setsel(s, e + 1)
w.buf:cut()
w.buf:input(text)
w.buf:history 'end'
if not a then
w.buf:setsel(s, w:cur())
end
w:visible()
end

local function grep_filter(fn)
if fn == 'red.dump' then return false end
local ext = { 'o', 'ko', 'exe', 'a' }
Expand Down Expand Up @@ -173,7 +121,7 @@ function proc.sub(w, text, glob)
else
a = { text }
end
text_replace(w, not not glob, function(text, a, b)
w:text_replace(function(text, a, b)
if glob then
if not b then
return text:find(a)
Expand Down Expand Up @@ -266,7 +214,7 @@ end
proc["dos2unix"] = function(w)
w = w:winmenu()
if not w then return end
text_replace(w, false, function(text)
w:text_replace(function(text)
local t = text:gsub("\r", "")
return t
end)
Expand All @@ -281,7 +229,7 @@ proc["i+"] = function(w)
if tab_sp then
tab = string.rep(" ", ts)
end
text_replace(w, false, function(text)
w:text_replace(function(text)
local t = ''
for l in text:lines(true) do
t = t .. tab .. l
Expand All @@ -299,7 +247,7 @@ proc["i-"] = function(w)
if tab_sp then
tab = string.rep(" ", ts)
end
text_replace(w, false, function(text)
w:text_replace(function(text)
local t = ''
for l in text:lines(true) do
if l:startswith(tab) then
Expand Down
54 changes: 54 additions & 0 deletions data/lib/red/win.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,60 @@ function win:nodirty()
self.buf:dirty(false)
end

local function cur_skip(text, pos)
local l = 1
local k = 0
while l < (pos or 1) do
local len = utf.next(text, l)
if len == 0 then
break
end
k = k + 1
l = l + len
end
return k
end

function win:text_match(fn, ...)
local w = self
local s, e = w.buf.cur, #w.buf.text
local text = w.buf:gettext(s, e)
local start, fin = fn(text, ...)
if not start then
s, e = 1, w.buf.cur
text = w.buf:gettext(s, e)
start, fin = fn(text, ...)
end
if not start then
return
end
w.buf:resetsel()
w.buf.cur = s + cur_skip(text, start)
fin = s + cur_skip(text, fin + 1)
w.buf:setsel(w.buf.cur, fin)
w.buf.cur = fin
w:visible()
end

function win:text_replace(fn, a, b)
local w = self
if a and (not w.buf:issel() or not b) then
return w:text_match(fn, a)
end
local s, e = w.buf:range()
local text = w.buf:gettext(s, e)
text = fn(text, a, b)
w.buf:history 'start'
w.buf:setsel(s, e + 1)
w.buf:cut()
w.buf:input(text)
w.buf:history 'end'
if not a then
w.buf:setsel(s, w:cur())
end
w:visible()
end

function win:event(r, v, a, b)
if not r then return end
local mx, my = input.mouse()
Expand Down

0 comments on commit 0d4c838

Please sign in to comment.