# HG changeset patch # User Miles Bader # Date 1167962947 0 # Node ID e566d4fc8dd2f942dd507d06df9b3b1a5d729d82 # Parent 2036fbeca1f25e2b4f5180570f5fe7107f659b75 Update from erc--emacs--22 Highlights: - New /RECONNECT command. - Improve default method for auto-identify to nickserv. - Fix another erc-iswitchb bug. - Fix reconnect lockup (defaulting to twice before giving up). - Fix reconnect on ban. Revision: emacs@sv.gnu.org/emacs--devo--0--patch-587 Creator: Michael Olson diff -r 2036fbeca1f2 -r e566d4fc8dd2 etc/ERC-NEWS --- a/etc/ERC-NEWS Thu Jan 04 22:14:36 2007 +0000 +++ b/etc/ERC-NEWS Fri Jan 05 02:09:07 2007 +0000 @@ -8,6 +8,20 @@ `erc-ssl' with `erc-select-ssl' as its alias. The function that was known as `erc' is now `erc-open'. +** New command: /RECONNECT +This command tries to reconnect to the current IRC server exactly +once. It does not work in server buffers (throws an error before the +command is run), but works in query and channel buffers. + +** New options + +*** erc-server-reconnect-attempts: Determines the number of +reconnection attempts that ERC will make per server. + +*** erc-server-reconnect-timeout: New option that determines the +amount of time, in seconds, that ERC will wait between successive +reconnect attempts. + ** Changes and additions to modules *** Channel lists (erc-list.el) diff -r 2036fbeca1f2 -r e566d4fc8dd2 lisp/erc/ChangeLog --- a/lisp/erc/ChangeLog Thu Jan 04 22:14:36 2007 +0000 +++ b/lisp/erc/ChangeLog Fri Jan 05 02:09:07 2007 +0000 @@ -1,3 +1,56 @@ +2006-12-28 Michael Olson + + * erc-list.el: Change header to mention that this is part of ERC, + rather than GNU Emacs. + + * erc-networks.el (erc-server-alist): Add Ars OpenIRC and + LinuxChix networks. Thanks to Angelina Carlton for mentioning + them. Properly escape periods in Konfido.Net and Kewl.Org. + (erc-networks-alist): Add entries for Ars and LinuxChix, though + the latter does not actually provide an announced network name. + + * erc-services.el (erc-nickserv-identify-mode): Add 'both method, + which waits for a NickServ message if the network supports it, + otherwise sends the password after connecting. + (erc-nickserv-identify-mode): Default to 'both. + (erc-nickserv-passwords): Add OFTC and Azzurra to custom options. + (erc-nickserv-alist): Indentation fix. + (erc-nickserv-identify-on-connect) + (erc-nickserv-identify-on-nick-change): Handle 'both method. + +2006-12-28 Leo (tiny change) + + * erc.el (erc-iswitchb): Wrap body in unwind-protect so that + hitting C-g does not leave iswitchb-mode on. + +2006-12-27 Michael Olson + + * erc.el (erc-cmd-RECONNECT): New command that calls + erc-server-reconnect. + + * erc-backend.el (erc-server-reconnect-count): New server variable + that keeps track of reconnection attempts. + (erc-server-reconnect-attempts): New option that determines the + number of reconnection attempts that ERC will make per server. + (erc-server-reconnect-timeout): New option that determines the + amount of time, in seconds, that ERC will wait between successive + reconnect attempts. + (erc-server-reconnect): New function that reestablishes the + current IRC connection. Move some commands from + erc-process-sentinel-1 here. + (erc-process-sentinel-1): If we have been disconnected, loop until + we either reconnect or run out of attempts. + (erc-server-reconnect-p): Move higher and make this a defsubst, + since I'm worried about the current buffer changing from + underneath us. Implement limit of number of reconnect attempts.. + + * erc.texi (Getting Started): Update for /RECONNECT command. + +2006-12-26 Michael Olson + + * erc.el (erc-open): Restore old point correctly, or at least get + closer to doing so than before. + 2006-12-13 Leo (tiny change) * erc.el (erc-iswitchb): Temporarily enable iswitchb mode if it @@ -38,7 +91,7 @@ (erc-update-current-channel-member, erc-load-script): (erc-mode-line-away-status-format): Doc fixes. -2006-11-20 Andrea Russo +2006-11-20 Andrea Russo (tiny change) * erc-dcc.el (erc-dcc-chat-setup): Initialize `erc-input-marker' before calling `erc-display-prompt'. @@ -111,7 +164,7 @@ `erc-show-my-nick' is non-nil. (erc-compute-server): Doc fix. -2006-10-01 John J Foerch +2006-10-01 John J Foerch (tiny change) * erc-stamp.el (erc-insert-timestamp-right): Exclude the newline from the erc-timestamp field. @@ -121,7 +174,7 @@ * erc-nicklist.el (erc-nicklist-insert-contents): Add missing parenthesis. Thanks to Stephan Stahl for the report. -2006-09-10 Eric Hanchrow +2006-09-10 Eric Hanchrow (tiny change) * erc.el (erc-cmd-IGNORE): Prompt user if this might be a regexp instead of a single user. @@ -230,6 +283,13 @@ * NEWS: Added note about these changes. +2006-08-20 Diane Murray + + * erc-backend.el (erc-process-sentinel-1): Doc fix. Let + `erc-server-reconnect-p' check all condition cases. + (erc-server-reconnect-p): Moved rest of checks from + `erc-process-sentinel-1' to here. Now takes an argument, EVENT. + 2006-08-21 Diane Murray * erc-track.el (erc-track-mode-line-mouse-face): New variable. @@ -242,6 +302,18 @@ (erc-menu-definition): Name the menu "ERC" instead of "IRC" to avoid confusion with rcirc and other clients. + * erc-backend.el (erc-server-banned): New variable. + (erc-server-connect): Set `erc-server-banned' to nil. + (erc-process-sentinel-1): Use `erc-server-reconnect-p'. + (erc-server-reconnect-p): New function. Return non-nil if the + user wants automatic reconnects and if the user has not been + banned from the server. This should fix a bug where ERC gets into + a loop trying to reconnect with no way to stop it when the user is + denied access to the server due to a server ban. It might also + help when Tor users are blocked from freenode if freenode servers + send the 465 message before disconnecting. + (465): Handle "banned from server" error notices. + 2006-08-13 Romain Francoise * erc-match.el (erc-log-matches-make-buffer): End `y-or-n-p' diff -r 2036fbeca1f2 -r e566d4fc8dd2 lisp/erc/erc-backend.el --- a/lisp/erc/erc-backend.el Thu Jan 04 22:14:36 2007 +0000 +++ b/lisp/erc/erc-backend.el Fri Jan 05 02:09:07 2007 +0000 @@ -179,10 +179,18 @@ This variable is buffer-local.") (make-variable-buffer-local 'erc-server-connected) +(defvar erc-server-reconnect-count 0 + "Number of times we have failed to reconnect to the current server.") +(make-variable-buffer-local 'erc-server-reconnect-count) + (defvar erc-server-quitting nil "Non-nil if the user requests a quit.") (make-variable-buffer-local 'erc-server-quitting) +(defvar erc-server-banned nil + "Non-nil if the user is denied access because of a server ban.") +(make-variable-buffer-local 'erc-server-banned) + (defvar erc-server-lines-sent nil "Line counter.") (make-variable-buffer-local 'erc-server-lines-sent) @@ -259,6 +267,23 @@ :group 'erc-server :type 'boolean) +(defcustom erc-server-reconnect-attempts 2 + "The number of times that ERC will attempt to reestablish a +broken connection, or t to always attempt to reconnect. + +This only has an effect if `erc-server-auto-reconnect' is non-nil." + :group 'erc-server + :type '(choice (const :tag "Always reconnect" t) + integer)) + +(defcustom erc-server-reconnect-timeout 1 + "The amount of time, in seconds, that ERC will wait between +successive reconnect attempts. + +If a key is pressed while ERC is waiting, it will stop waiting." + :group 'erc-server + :type 'number) + (defcustom erc-split-line-length 440 "*The maximum length of a single message. If a message exceeds this size, it is broken into multiple ones. @@ -434,6 +459,7 @@ (message "%s...done" msg)) ;; Misc server variables (setq erc-server-quitting nil) + (setq erc-server-banned nil) (setq erc-server-last-sent-time (erc-current-time)) (setq erc-server-last-ping-time (erc-current-time)) (setq erc-server-lines-sent 0) @@ -457,6 +483,21 @@ "Opening connection..\n") (erc-login))) +(defun erc-server-reconnect () +"Reestablish the current IRC connection. +Make sure you are in an ERC buffer when running this." + (let ((server (erc-server-buffer))) + (unless (and server + (buffer-live-p server)) + (error "Couldn't switch to server buffer")) + (with-current-buffer server + (erc-update-mode-line) + (erc-set-active-buffer (current-buffer)) + (setq erc-server-last-sent-time 0) + (setq erc-server-lines-sent 0) + (erc-open erc-session-server erc-session-port erc-server-current-nick + erc-session-user-full-name t erc-session-password)))) + (defun erc-server-filter-function (process string) "The process filter for the ERC server." (with-current-buffer (process-buffer process) @@ -485,11 +526,24 @@ (match-end 0)))) (erc-parse-server-response process line))))))) +(defsubst erc-server-reconnect-p (event) + "Return non-nil if ERC should attempt to reconnect automatically. +EVENT is the message received from the closed connection process." + (and erc-server-auto-reconnect + (not erc-server-banned) + ;; make sure we don't infinitely try to reconnect, unless the + ;; user wants that + (or (eq erc-server-reconnect-attempts t) + (and (integerp erc-server-reconnect-attempts) + (< erc-server-reconnect-count erc-server-reconnect-attempts))) + (not (string-match "^deleted" event)) + ;; open-network-stream-nowait error for connection refused + (not (string-match "^failed with code 111" event)))) + (defun erc-process-sentinel-1 (event) - "This will be called when erc-process-sentinel has decided that we -are going to quit. Determine whether user has quit or whether erc has -been terminated. Conditionally try to reconnect and take appropriate -action." + "Called when `erc-process-sentinel' has decided that we're disconnecting. +Determine whether user has quit or whether erc has been terminated. +Conditionally try to reconnect and take appropriate action." (if erc-server-quitting ;; normal quit (progn @@ -498,25 +552,26 @@ (set-buffer-modified-p nil) (kill-buffer (current-buffer)))) ;; unexpected disconnect - (erc-display-message nil 'error (current-buffer) - (if erc-server-auto-reconnect - 'disconnected - 'disconnected-noreconnect)) - (erc-update-mode-line) - (erc-set-active-buffer (current-buffer)) - (setq erc-server-last-sent-time 0) - (setq erc-server-lines-sent 0) - (if (and erc-server-auto-reconnect - (not (string-match "^deleted" event)) - ;; open-network-stream-nowait error for connection refused - (not (string-match "^failed with code 111" event))) - ;; Yuck, this should perhaps funcall - ;; erc-server-reconnect-function with no args - (erc-open erc-session-server erc-session-port erc-server-current-nick - erc-session-user-full-name t erc-session-password) - ;; terminate, do not reconnect - (erc-display-message nil 'error (current-buffer) - 'terminated ?e event)))) + (let ((again t)) + (while again + (setq again nil) + (erc-display-message nil 'error (current-buffer) + (if (erc-server-reconnect-p event) + 'disconnected + 'disconnected-noreconnect)) + (if (erc-server-reconnect-p event) + (condition-case err + (progn + (erc-server-reconnect) + (setq erc-server-reconnect-count 0)) + (error (when (integerp erc-server-reconnect-attempts) + (setq erc-server-reconnect-count + (1+ erc-server-reconnect-count)) + (sit-for erc-server-reconnect-timeout) + (setq again t)))) + ;; terminate, do not reconnect + (erc-display-message nil 'error (current-buffer) + 'terminated ?e event)))))) (defun erc-process-sentinel (cproc event) "Sentinel function for ERC process." @@ -1708,6 +1763,14 @@ ?c (second (erc-response.command-args parsed)) ?m (erc-response.contents parsed))) +(define-erc-response-handler (465) + "You are banned from this server." nil + (setq erc-server-banned t) + ;; show the server's message, as a reason might be provided + (erc-display-error-notice + parsed + (erc-response.contents parsed))) + (define-erc-response-handler (474) "Banned from channel errors" nil (erc-display-message parsed '(notice error) nil @@ -1741,7 +1804,7 @@ (erc-display-message parsed '(error notice) 'active 's482 ?c channel ?m message))) -(define-erc-response-handler (431 445 446 451 462 463 464 465 481 483 484 485 +(define-erc-response-handler (431 445 446 451 462 463 464 481 483 484 485 491 501 502) ;; 431 - No nickname given ;; 445 - SUMMON has been disabled @@ -1750,7 +1813,6 @@ ;; 462 - Unauthorized command (already registered) ;; 463 - Your host isn't among the privileged ;; 464 - Password incorrect - ;; 465 - You are banned from this server ;; 481 - Need IRCop privileges ;; 483 - You can't kill a server! ;; 484 - Your connection is restricted! diff -r 2036fbeca1f2 -r e566d4fc8dd2 lisp/erc/erc-networks.el --- a/lisp/erc/erc-networks.el Thu Jan 04 22:14:36 2007 +0000 +++ b/lisp/erc/erc-networks.el Fri Jan 05 02:09:07 2007 +0000 @@ -64,6 +64,7 @@ ("AngelEyez: Random server" AngelEyez "irc.angeleyez.net" ((6666 7000))) ("AnotherNet: Random server" Anothernet "irc.another.net" (6667 7000 )) ("ArabChat: Random server" ArabChat "irc.arabchat.org" ((6660 6667))) + ("Ars-OpenIRC: Random server" Ars "irc.arstechnica.com" 6667) ("AsiaTalk: Random server" AsiaTalk "irc.asiatalk.org" ((6667 6669) 7000 )) ("AstroLink: Random server" AstroLink "irc.astrolink.org" ((6660 6667))) ("Asylumnet: Random server" Asylumnet "irc.asylum-net.org" ((6661 6669) 7000 7777 )) @@ -280,12 +281,12 @@ ("K0wNet: Random server" K0wNet "irc.k0w.net" ((6660 6669))) ("KDFSnet: Random server" KDFSnet "irc.kdfs.net" ((6667 6669))) ("Kemik: Random server" Kemik "irc.kemik.net" 6667) - ("Kewl.Org: Random server" Kewl.Org "irc.kewl.org" (6667 7000 )) + ("Kewl.Org: Random server" Kewl\.Org "irc.kewl.org" (6667 7000 )) ("Kickchat: Random server" Kickchat "irc.kickchat.com" ((6660 6669) 7000 )) ("Kidsworld: Random server" KidsWorld "irc.kidsworld.org" ((6666 6669))) ("Knightnet: AF, ZA, Durban" Knightnet "orc.dbn.za.knightnet.net" (6667 5555 )) ("Knightnet: US, CA, Goldengate" Knightnet "goldengate.ca.us.knightnet.net" (6667 5555 )) - ("Konfido.Net: Random server" Konfido.Net "irc.konfido.net" 6667) + ("Konfido.Net: Random server" Konfido\.Net "irc.konfido.net" 6667) ("KreyNet: Random server" Kreynet "irc.krey.net" 6667) ("Krono: Random server" Krono "irc.krono.net" ((6660 6669) 7000 )) ("Krushnet: Random server" Krushnet "irc.krushnet.org" 6667) @@ -294,6 +295,7 @@ ("LagNet: AF, ZA, Johannesburg" LagNet "mystery.lagnet.org.za" 6667) ("Librenet: Random server" Librenet "irc.librenet.net" 6667) ("LinkNet: Random server" LinkNet "irc.link-net.org" ((6667 6669))) + ("LinuxChix: Random server" LinuxChix "irc.linuxchix.org" 6667) ("Liquidized: Random server" Liquidized "irc.liquidized.net" (6667 7000 )) ("M-IRC: Random server" M-IRC "irc.m-sys.org" ((6667 6669))) ("MagicStar: Random server" MagicStar "irc.magicstar.net" 6667) @@ -457,6 +459,7 @@ (AngelEyez "angeleyez.net") (Anothernet "another.net") (ArabChat "arabchat.org") + (Ars "arstechnica.com") (AsiaTalk "asiatalk.org") (AstroLink "astrolink.org") (Asylumnet "asylumnet.org") @@ -586,6 +589,7 @@ (LagNet "lagnet.org.za") (Librenet "librenet.net") (LinkNet "link-net.org") + (LinuxChix "cats\.meow\.at\\|linuxchix\.org") (Liquidized "liquidized.net") (M-IRC "m-sys.org") (MagicStar "magicstar.net") diff -r 2036fbeca1f2 -r e566d4fc8dd2 lisp/erc/erc-services.el --- a/lisp/erc/erc-services.el Thu Jan 04 22:14:36 2007 +0000 +++ b/lisp/erc/erc-services.el Fri Jan 05 02:09:07 2007 +0000 @@ -94,7 +94,7 @@ (interactive (list (intern (completing-read "Choose Nickserv identify mode (RET to disable): " - '(("autodetect") ("nick-change")) nil t)))) + '(("autodetect") ("nick-change") ("both")) nil t)))) (cond ((eq mode 'autodetect) (setq erc-nickserv-identify-mode 'autodetect) (add-hook 'erc-server-NOTICE-functions @@ -111,6 +111,14 @@ 'erc-nickserv-identify-on-nick-change) (remove-hook 'erc-server-NOTICE-functions 'erc-nickserv-identify-autodetect)) + ((eq mode 'both) + (setq erc-nickserv-identify-mode 'both) + (add-hook 'erc-server-NOTICE-functions + 'erc-nickserv-identify-autodetect) + (add-hook 'erc-after-connect + 'erc-nickserv-identify-on-connect) + (add-hook 'erc-nick-changed-functions + 'erc-nickserv-identify-on-nick-change)) (t (setq erc-nickserv-identify-mode nil) (remove-hook 'erc-server-NOTICE-functions @@ -120,22 +128,25 @@ (remove-hook 'erc-nick-changed-functions 'erc-nickserv-identify-on-nick-change)))) -(defcustom erc-nickserv-identify-mode 'autodetect +(defcustom erc-nickserv-identify-mode 'both "The mode which is used when identifying to Nickserv. Possible settings are:. 'autodetect - Identify when the real Nickserv sends an identify request. 'nick-change - Identify when you change your nickname. +'both - Do the former if the network supports it, otherwise do the + latter. nil - Disables automatic Nickserv identification. You can also use M-x erc-nickserv-identify-mode to change modes." :group 'erc-services :type '(choice (const autodetect) (const nick-change) + (const both) (const nil)) :set (lambda (sym val) - (set-default sym val) + (set sym val) (erc-nickserv-identify-mode val))) (defcustom erc-prompt-for-nickserv-password t @@ -156,12 +167,14 @@ (list :tag "Network" (choice :tag "Network name" (const freenode) + (const OFTC) (const DALnet) (const GalaxyNet) (const SlashNET) (const BRASnet) (const iip) (const Austnet) + (const Azzurra) (symbol :tag "Network name")) (repeat :tag "Nickname and password" (cons :tag "Identity" @@ -209,24 +222,24 @@ "IDENTIFY" nil "") - (Austnet - "NickOP!service@austnet.org" - "/msg\\s-NickOP@austnet.org\\s-identify\\s-" - "nickop@austnet.org" - "identify" - nil) - (Azzurra - "NickServ!service@azzurra.org" - "/ns\\s-IDENTIFY\\s-password" - "NickServ" - "IDENTIFY" - nil) - (OFTC - "NickServ!services@services.oftc.net" - "/msg\\s-NickServ\\s-IDENTIFY\\s-\^_password" - "NickServ" - "IDENTIFY" - nil)) + (Austnet + "NickOP!service@austnet.org" + "/msg\\s-NickOP@austnet.org\\s-identify\\s-" + "nickop@austnet.org" + "identify" + nil) + (Azzurra + "NickServ!service@azzurra.org" + "/ns\\s-IDENTIFY\\s-password" + "NickServ" + "IDENTIFY" + nil) + (OFTC + "NickServ!services@services.oftc.net" + "/msg\\s-NickServ\\s-IDENTIFY\\s-\^_password" + "NickServ" + "IDENTIFY" + nil)) "Alist of NickServer details, sorted by network. Every element in the list has the form \(SYMBOL NICKSERV REGEXP NICK KEYWORD USE-CURRENT ANSWER) @@ -279,14 +292,18 @@ (defun erc-nickserv-identify-on-connect (server nick) "Identify to Nickserv after the connection to the server is established." - (unless (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password)) + (unless (or (and (null erc-nickserv-passwords) + (null erc-prompt-for-nickserv-password)) + (and (eq erc-nickserv-identify-mode 'both) + (nth 2 (assoc (erc-network) erc-nickserv-alist)))) (erc-nickserv-call-identify-function nick))) (defun erc-nickserv-identify-on-nick-change (nick old-nick) "Identify to Nickserv whenever your nick changes." - (unless (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password)) + (unless (or (and (null erc-nickserv-passwords) + (null erc-prompt-for-nickserv-password)) + (and (eq erc-nickserv-identify-mode 'both) + (nth 2 (assoc (erc-network) erc-nickserv-alist)))) (erc-nickserv-call-identify-function nick))) (defun erc-nickserv-call-identify-function (nickname) diff -r 2036fbeca1f2 -r e566d4fc8dd2 lisp/erc/erc.el --- a/lisp/erc/erc.el Thu Jan 04 22:14:36 2007 +0000 +++ b/lisp/erc/erc.el Fri Jan 05 02:09:07 2007 +0000 @@ -1672,21 +1672,22 @@ (require 'iswitchb)) (let ((enabled iswitchb-mode)) (or enabled (iswitchb-mode 1)) - (let ((iswitchb-make-buflist-hook - (lambda () - (setq iswitchb-temp-buflist - (mapcar 'buffer-name - (erc-buffer-list - nil - (when arg erc-server-process))))))) - (switch-to-buffer - (iswitchb-read-buffer - "Switch-to: " - (if (boundp 'erc-modified-channels-alist) - (buffer-name (caar (last erc-modified-channels-alist))) - nil) - t))) - (or enabled (iswitchb-mode -1)))) + (unwind-protect + (let ((iswitchb-make-buflist-hook + (lambda () + (setq iswitchb-temp-buflist + (mapcar 'buffer-name + (erc-buffer-list + nil + (when arg erc-server-process))))))) + (switch-to-buffer + (iswitchb-read-buffer + "Switch-to: " + (if (boundp 'erc-modified-channels-alist) + (buffer-name (caar (last erc-modified-channels-alist))) + nil) + t))) + (or enabled (iswitchb-mode -1))))) (defun erc-channel-list (proc) "Return a list of channel buffers. @@ -1888,10 +1889,11 @@ (connected-p (unless connect erc-server-connected)) (buffer (erc-get-buffer-create server port channel)) (old-buffer (current-buffer)) - (old-point (point)) + old-point continued-session) (erc-update-modules) (set-buffer buffer) + (setq old-point (point)) (erc-mode) (setq erc-server-announced-name server-announced-name) (setq erc-server-connected connected-p) @@ -3165,6 +3167,12 @@ (defalias 'erc-cmd-GQ 'erc-cmd-GQUIT) (put 'erc-cmd-GQUIT 'do-not-parse-args t) +(defun erc-cmd-RECONNECT () + "Try to reconnect to the current IRC server." + (setq erc-server-reconnect-count 0) + (erc-server-reconnect) + t) + (defun erc-cmd-SERVER (server) "Connect to SERVER, leaving existing connection intact." (erc-log (format "cmd: SERVER: %s" server)) diff -r 2036fbeca1f2 -r e566d4fc8dd2 man/ChangeLog --- a/man/ChangeLog Thu Jan 04 22:14:36 2007 +0000 +++ b/man/ChangeLog Fri Jan 05 02:09:07 2007 +0000 @@ -1,3 +1,7 @@ +2007-01-05 Michael Olson + + * erc.texi (Getting Started): Update for /RECONNECT command. + 2007-01-04 Richard Stallman * ebrowse.texi: Change C-c b to C-c C-m. diff -r 2036fbeca1f2 -r e566d4fc8dd2 man/erc.texi --- a/man/erc.texi Thu Jan 04 22:14:36 2007 +0000 +++ b/man/erc.texi Fri Jan 05 02:09:07 2007 +0000 @@ -274,6 +274,11 @@ Once ERC is loaded, the command @kbd{M-x erc} will start ERC and prompt for the server to connect to. +If the connection goes away at some point, ERC will try to reconnect +automatically. If it fails to reconnect, and you want to try to +manually reestablish the connection at some later point, switch to an +ERC buffer and run the /RECONNECT command. + @c PRE5_2: Sample session, including: @c - connect to Freenode @c - /join #emacs