diff --git a/doc/irc.luadoc b/doc/irc.luadoc
index 2e42034..85dc229 100644
--- a/doc/irc.luadoc
+++ b/doc/irc.luadoc
@@ -137,8 +137,8 @@ function irc:shutdown()
--
OnTopic(channel, topic)
-- OnTopicInfo(channel, creator, timeCreated)
-- OnKick(channel, nick, kicker, reason)
* (kicker is a user
table)
--- OnUserModeIs(modes)
--- OnChannelModeIs(user, channel, modes)
+-- OnUserMode(modes)
+-- OnChannelMode(user, channel, modes)
-- OnModeChange(user, target, modes)
*
--
-- * Event also invoked for yourself.
diff --git a/handlers.lua b/handlers.lua
new file mode 100644
index 0000000..2919a49
--- /dev/null
+++ b/handlers.lua
@@ -0,0 +1,140 @@
+local pairs = pairs
+local error = error
+local tonumber = tonumber
+
+module "irc"
+
+handlers = {}
+
+handlers["PING"] = function(o, prefix, query)
+ o:send("PONG :%s", query)
+end
+
+handlers["001"] = function(o)
+ o.authed = true
+end
+
+handlers["PRIVMSG"] = function(o, prefix, channel, message)
+ o:invoke("OnChat", parsePrefix(prefix), channel, message)
+end
+
+handlers["NOTICE"] = function(o, prefix, channel, message)
+ o:invoke("OnNotice", parsePrefix(prefix), channel, message)
+end
+
+handlers["JOIN"] = function(o, prefix, channel)
+ local user = parsePrefix(prefix)
+ if o.track_users then
+ if user.nick == o.nick then
+ o.channels[channel] = {users = {}}
+ else
+ o.channels[channel].users[user.nick] = user
+ end
+ end
+
+ o:invoke("OnJoin", user, channel)
+end
+
+handlers["PART"] = function(o, prefix, channel, reason)
+ local user = parsePrefix(prefix)
+ if o.track_users then
+ if user.nick == o.nick then
+ o.channels[channel] = nil
+ else
+ o.channels[channel].users[user.nick] = nil
+ end
+ end
+ o:invoke("OnPart", user, channel, reason)
+end
+
+handlers["QUIT"] = function(o, prefix, msg)
+ local user = parsePrefix(prefix)
+ if o.track_users then
+ for channel, v in pairs(o.channels) do
+ v.users[user.nick] = nil
+ end
+ end
+ o:invoke("OnQuit", user, msg)
+end
+
+handlers["NICK"] = function(o, prefix, newnick)
+ local user = parsePrefix(prefix)
+ if o.track_users then
+ for channel, v in pairs(o.channels) do
+ local users = v.users
+ local oldinfo = users[user.nick]
+ if oldinfo then
+ users[newnick] = oldinfo
+ users[user.nick] = nil
+ o:invoke("NickChange", user, newnick, channel)
+ end
+ end
+ else
+ o:invoke("NickChange", user, newnick)
+ end
+end
+
+--NAMES list
+handlers["353"] = function(o, prefix, me, chanType, channel, names)
+ if o.track_users then
+ o.channels[channel] = o.channels[channel] or {users = {}, type = chanType}
+
+ local users = o.channels[channel].users
+ for nick in names:gmatch("(%S+)") do
+ local access, name = parseNick(nick)
+ users[name] = {type = access}
+ end
+ end
+end
+
+--end of NAMES
+handlers["366"] = function(o, prefix, me, channel, msg)
+ if o.track_users then
+ o:invoke("NameList", channel, msg)
+ end
+end
+
+--no topic
+handlers["331"] = function(o, prefix, me, channel)
+ o:invoke("OnTopic", channel, nil)
+end
+
+--new topic
+handlers["TOPIC"] = function(o, prefix, channel, topic)
+ o:invoke("OnTopic", channel, topic)
+end
+
+handlers["332"] = function(o, prefix, me, channel, topic)
+ o:invoke("OnTopic", channel, topic)
+end
+
+--topic creation info
+handlers["333"] = function(o, prefix, me, channel, nick, time)
+ o:invoke("OnTopicInfo", channel, nick, tonumber(time))
+end
+
+handlers["KICK"] = function(o, prefix, channel, kicked, reason)
+ o:invoke("OnKick", channel, kicked, parsePrefix(prefix), reason)
+end
+
+--RPL_UMODEIS
+--To answer a query about a client's own mode, RPL_UMODEIS is sent back
+handlers["221"] = function(o, prefix, user, modes)
+ o:invoke("OnUserMode", modes)
+end
+
+--RPL_CHANNELMODEIS
+--The result from common irc servers differs from that defined by the rfc
+handlers["324"] = function(o, prefix, user, channel, modes)
+ o:invoke("OnChannelMode", channel, modes)
+end
+
+handlers["MODE"] = function(o, prefix, target, modes)
+ o:invoke("OnModeChange", parsePrefix(prefix), target, modes)
+end
+
+handlers["ERROR"] = function(o, prefix, message)
+ o:invoke("OnDisconnect", message, true)
+ o:shutdown()
+ error(message, 3)
+end
diff --git a/init.lua b/init.lua
index ff7ac38..1e3b46e 100644
--- a/init.lua
+++ b/init.lua
@@ -19,6 +19,7 @@ _META = meta
require "irc.util"
require "irc.asyncoperations"
+require "irc.handlers"
local meta_preconnect = {}
function meta_preconnect.__index(o, k)
@@ -171,140 +172,7 @@ function meta:think()
end
end
-local handlers = {}
-
-handlers["PING"] = function(o, prefix, query)
- o:send("PONG :%s", query)
-end
-
-handlers["001"] = function(o)
- o.authed = true
-end
-
-handlers["PRIVMSG"] = function(o, prefix, channel, message)
- o:invoke("OnChat", parsePrefix(prefix), channel, message)
-end
-
-handlers["NOTICE"] = function(o, prefix, channel, message)
- o:invoke("OnNotice", parsePrefix(prefix), channel, message)
-end
-
-handlers["JOIN"] = function(o, prefix, channel)
- local user = parsePrefix(prefix)
- if o.track_users then
- if user.nick == o.nick then
- o.channels[channel] = {users = {}}
- else
- o.channels[channel].users[user.nick] = user
- end
- end
-
- o:invoke("OnJoin", user, channel)
-end
-
-handlers["PART"] = function(o, prefix, channel, reason)
- local user = parsePrefix(prefix)
- if o.track_users then
- if user.nick == o.nick then
- o.channels[channel] = nil
- else
- o.channels[channel].users[user.nick] = nil
- end
- end
- o:invoke("OnPart", user, channel, reason)
-end
-
-handlers["QUIT"] = function(o, prefix, msg)
- local user = parsePrefix(prefix)
- if o.track_users then
- for channel, v in pairs(o.channels) do
- v.users[user.nick] = nil
- end
- end
- o:invoke("OnQuit", user, msg)
-end
-
-handlers["NICK"] = function(o, prefix, newnick)
- local user = parsePrefix(prefix)
- if o.track_users then
- for channel, v in pairs(o.channels) do
- local users = v.users
- local oldinfo = users[user.nick]
- if oldinfo then
- users[newnick] = oldinfo
- users[user.nick] = nil
- o:invoke("NickChange", user, newnick, channel)
- end
- end
- else
- o:invoke("NickChange", user, newnick)
- end
-end
-
---NAMES list
-handlers["353"] = function(o, prefix, me, chanType, channel, names)
- if o.track_users then
- o.channels[channel] = o.channels[channel] or {users = {}, type = chanType}
-
- local users = o.channels[channel].users
- for nick in names:gmatch("(%S+)") do
- local access, name = parseNick(nick)
- users[name] = {type = access}
- end
- end
-end
-
---end of NAMES
-handlers["366"] = function(o, prefix, me, channel, msg)
- if o.track_users then
- o:invoke("NameList", channel, msg)
- end
-end
-
---no topic
-handlers["331"] = function(o, prefix, me, channel)
- o:invoke("OnTopic", channel, nil)
-end
-
---new topic
-handlers["TOPIC"] = function(o, prefix, channel, topic)
- o:invoke("OnTopic", channel, topic)
-end
-
-handlers["332"] = function(o, prefix, me, channel, topic)
- o:invoke("OnTopic", channel, topic)
-end
-
---topic creation info
-handlers["333"] = function(o, prefix, me, channel, nick, time)
- o:invoke("OnTopicInfo", channel, nick, tonumber(time))
-end
-
-handlers["KICK"] = function(o, prefix, channel, kicked, reason)
- o:invoke("OnKick", channel, kicked, parsePrefix(prefix), reason)
-end
-
---RPL_UMODEIS
---To answer a query about a client's own mode, RPL_UMODEIS is sent back
-handlers["221"] = function(o, prefix, user, modes)
- o:invoke("OnUserMode", modes)
-end
-
---RPL_CHANNELMODEIS
---The result from common irc servers differs from that defined by the rfc
-handlers["324"] = function(o, prefix, user, channel, modes)
- o:invoke("OnChannelMode", channel, modes)
-end
-
-handlers["MODE"] = function(o, prefix, target, modes)
- o:invoke("OnModeChange", parsePrefix(prefix), target, modes)
-end
-
-handlers["ERROR"] = function(o, prefix, message)
- o:invoke("OnDisconnect", message, true)
- o:shutdown()
- error(message, 3)
-end
+local handlers = handlers
function meta:handle(prefix, cmd, params)
local handler = handlers[cmd]