implement sed plugin

This commit is contained in:
q3k 2019-04-04 03:23:44 +02:00
parent d6b92f0593
commit 35efd44088

148
plugins/sed.lua Normal file
View file

@ -0,0 +1,148 @@
local LastMessage = {}
-- Meeeeh.
local function esc(x)
return (x:gsub('%%', '%%%%')
:gsub('^%^', '%%^')
:gsub('%$$', '%%$')
:gsub('%(', '%%(')
:gsub('%)', '%%)')
:gsub('%.', '%%.')
:gsub('%[', '%%[')
:gsub('%]', '%%]')
:gsub('%*', '%%*')
:gsub('%+', '%%+')
:gsub('%-', '%%-')
:gsub('%?', '%%?'))
end
local memoize = function(Username, Channel, Message)
if LastMessage[Channel] == nil then
LastMessage[Channel] = {}
end
LastMessage[Channel][Username] = Message
end
local sed = function(Username, Channel, Message)
if LastMessage[Channel] == nil then
return
end
if LastMessage[Channel][Username] == nil then
return
end
local Last = LastMessage[Channel][Username]
if #Message < 4 then
return
end
local Delim = Message:sub(2,2)
if Message:sub(1,1) ~= "s" then
return
end
local Global = false
local Inner = Message:sub(3, -2)
if #Message > 4 and Message:sub(-2, -1) == (Delim .. "g") then
Global = true
Inner = Message:sub(3,-3)
elseif Message:sub(-1,-1) ~= Delim then
return
end
if #Inner < 1 then
return
end
-- Meh.
local First = ""
local Second = ""
local Found = false
for i = 0, #Inner do
local Cur = Inner:sub(i, i)
if not Found then
if Cur == Delim then
Found = true
else
First = First .. Cur
end
else
if Cur == Delim then
return
else
Second = Second .. Cur
end
end
end
if #First < 1 then
return
end
local n = 1
if Global then
n = nil
end
local Replaced = Last:gsub(esc(First), Second, n)
Channel:Say(Username .. " meant " .. Replaced)
-- memoize corrected version
memoize(Username, Channel, Replaced)
return true
end
local Test = false
-- Mun runtime has no pcall, detect this way.
if plugin == nil then
Test = true
end
if Test then
local Channel = {}
Channel.Say = function(chan, What)
chan.Said = What
end
local mustEqual = function(a, b)
if a ~= b then
print(tostring(a) .. " != " .. tostring(b))
end
end
memoize("q3k", Channel, "lorem ipsum dolor sit amet")
sed("q3k", Channel, "s,ipsum,foo,")
mustEqual(Channel.Said, "q3k meant lorem foo dolor sit amet")
Channel.Said = nil
memoize("q3k", Channel, "lorem ipsum dolor sit amet")
sed("q3k", Channel, "s,ipsum,foo/")
mustEqual(Channel.Said, nil)
sed("q3k", Channel, "s/no/don/t/")
mustEqual(Channel.Said, nil)
sed("q3k", Channel, "s///")
mustEqual(Channel.Said, nil)
sed("q3k", Channel, "s//")
mustEqual(Channel.Said, nil)
Channel.Said = nil
memoize("q3k", Channel, "barfoo barbaz foobar")
sed("q3k", Channel, "s/foo/what/g")
mustEqual(Channel.Said, "q3k meant barwhat barbaz whatbar")
Channel.Said = nil
memoize("q3k", Channel, "barfoo barbaz foobar")
sed("q3k", Channel, "s/foo/what/")
mustEqual(Channel.Said, "q3k meant barwhat barbaz foobar")
print("ok")
else
plugin.AddHook("irc.Message", "sed", function(Username, Channel, Message)
local replaced = sed(Username, Channel, Message)
if not replaced then
memoize(Username, Channel, Message)
end
end)
end