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