defmodule Nola.IRC.CorrectionPlugin do
@moduledoc """
# correction
* `s/pattern/replace` replace `pattern` by `replace` in the last matching message
"""
def irc_doc, do: @moduledoc
def start_link() do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
{:ok, _} = Registry.register(IRC.PubSub, "messages", [plugin: __MODULE__])
{:ok, _} = Registry.register(IRC.PubSub, "triggers", [plugin: __MODULE__])
{:ok, %{}}
end
# Trigger fallback
def handle_info({:irc, :trigger, _, m = %IRC.Message{}}, state) do
{:noreply, correction(m, state)}
end
def handle_info({:irc, :text, m = %IRC.Message{}}, state) do
{:noreply, correction(m, state)}
end
def correction(m, state) do
history = Map.get(state, key(m), [])
if String.starts_with?(m.text, "s/") do
case String.split(m.text, "/") do
["s", match, replace | _] ->
case Regex.compile(match) do
{:ok, reg} ->
repl = Enum.find(history, fn(m) -> Regex.match?(reg, m.text) end)
if repl do
new_text = String.replace(repl.text, reg, replace)
m.replyfun.("correction: <#{repl.sender.nick}> #{new_text}")
end
_ ->
m.replyfun.("correction: invalid regex")
end
_ -> m.replyfun.("correction: invalid regex format")
end
state
else
history = if length(history) > 100 do
{_, history} = List.pop_at(history, 99)
[m | history]
else
[m | history]
end
Map.put(state, key(m), history)
end
end
defp key(%{network: net, channel: chan}), do: "#{net}/#{chan}"
end