-- -- slack.lua: try to fix up UX when using the Slack IRC gateway -- -- Copyright (c) 2017, Přemysl Janouch -- -- Permission to use, copy, modify, and/or distribute this software for any -- purpose with or without fee is hereby granted, provided that the above -- copyright notice and this permission notice appear in all copies. -- -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- local servers = {} local read_servers = function (v) servers = {} for name in v:lower ():gmatch "[^,]+" do servers[name] = true end end degesch.setup_config { servers = { type = "string_array", default = "\"\"", comment = "list of server names that are Slack IRC gateways", on_change = read_servers } } -- We can handle external messages about what we've supposedly sent just fine, -- so let's get rid of that "[username] some message sent from the web UI" crap degesch.hook_irc (function (hook, server, line) local msg, us = degesch.parse (line), server.user if not servers[server.name] or msg.command ~= "PRIVMSG" or not us or msg.params[1]:lower () ~= us.nickname:lower () then return line end -- Taking a shortcut to avoid lengthy message reassembly local quoted_nick = us.nickname:gsub ("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") local text = line:match ("^.- PRIVMSG .- :%[" .. quoted_nick .. "%] (.*)$") if not text then return line end return ":" .. us.nickname .. "!" .. server.irc_user_host .. " PRIVMSG " .. msg.prefix:match "^[^!@]*" .. " :" .. text end) degesch.hook_completion (function (hook, data, word) local chan = degesch.current_buffer.channel local server = degesch.current_buffer.server if not chan or not servers[server.name] then return end -- In /commands there is typically no desire at all to add the at sign if data.location == 1 and data.words[1]:match "^/" then return end -- Handle both when the at sign is already there and when it is not local needle = word:gsub ("^@", ""):lower () local t = {} for i, chan_user in ipairs (chan.users) do local nick = chan_user.user.nickname if data.location == 0 then nick = nick .. ":" end if nick:sub (1, #needle):lower () == needle then table.insert (t, "@" .. nick) end end return t end)