changeset 75092:e566d4fc8dd2

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 <mwolson@gnu.org>
author Miles Bader <miles@gnu.org>
date Fri, 05 Jan 2007 02:09:07 +0000
parents 2036fbeca1f2
children 5b3d80ea3c0e
files etc/ERC-NEWS lisp/erc/ChangeLog lisp/erc/erc-backend.el lisp/erc/erc-networks.el lisp/erc/erc-services.el lisp/erc/erc.el man/ChangeLog man/erc.texi
diffstat 8 files changed, 257 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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  <mwolson@gnu.org>
+
+	* 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  <sdl.web@gmail.com>  (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  <mwolson@gnu.org>
+
+	* 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  <mwolson@gnu.org>
+
+	* erc.el (erc-open): Restore old point correctly, or at least get
+	closer to doing so than before.
+
 2006-12-13  Leo  <sdl.web@gmail.com>  (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  <rastandy@inventati.org>
+2006-11-20  Andrea Russo  <rastandy@inventati.org>  (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  <jjfoerch@earthlink.net>
+2006-10-01  John J Foerch  <jjfoerch@earthlink.net>  (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  <offby1@blarg.net>
+2006-09-10  Eric Hanchrow  <offby1@blarg.net>  (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  <disumu@x3y2z1.net>
+
+	* 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  <disumu@x3y2z1.net>
 
 	* 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  <romain@orebokech.com>
 
 	* erc-match.el (erc-log-matches-make-buffer): End `y-or-n-p'
--- 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!
--- 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")
--- 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-<password>"
-      "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-<password>"
+     "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)
--- 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))
--- 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  <mwolson@gnu.org>
+
+	* erc.texi (Getting Started): Update for /RECONNECT command.
+
 2007-01-04  Richard Stallman  <rms@gnu.org>
 
 	* ebrowse.texi: Change C-c b to C-c C-m.
--- 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