Subject: bug#30639: 25.1; ERC buffer name not unique, broken on reconnect [patch]

From: John Goerzen <[email-masked]>
Date: Tue, 27 Feb 2018 15:15:30 -0600

Hi,

Over at https://www.emacswiki.org/emacs/ErcBugs, there is a description
as follows:

"When you're in two channels with the same name, e.g. #hello, on
different networks, the buffers are called #hello and #hello<2>. Now, if
you temporarily lose your connection (e.g. unplug the network cable and
plug it back in) and ERC reconnects, #hello<2> will not be re-used, but
instead #hello<3> will be created."

I have observed this.  This all goes back to a bug in
erc/erc.el:erc-generate-new-buffer-name

The comments in the function as given are reasonable, but the logic
differs.  In particular, the test in the dolist always fails when
(get-buffer candidate) is nil; that is, the test always fails when the
buffer does not already exist.  This causes the test to drop through to
the section at the bottom every time, which results not only in the
server appending logic never being used, but also in the concatenation
of /server never being attempted.

Here is a working replacement:

  (defun erc-generate-new-buffer-name (server port target)
    "Create a new buffer name based on the arguments."
    (when (numberp port) (setq port (number-to-string port)))
    (let ((buf-name (or target
                        (or (let ((name (concat server ":" port)))
                              (when (> (length name) 1)
                                name))
                            ;; This fallback should in fact never happen
                            "*erc-server-buffer*")))
          buffer-name)
      ;; Reuse existing buffers, but not if the buffer is a connected server
      ;; buffer and not if its associated with a different server than the
      ;; current ERC buffer.
      ;; if buf-name is taken by a different connection (or by something !erc)
      ;; then see if "buf-name/server" meets the same criteria
      (dolist (candidate (list buf-name (concat buf-name "/" server)))
        (if (and (not buffer-name)
                 erc-reuse-buffers
                 (or (not (get-buffer candidate))
                     (or target
                         (with-current-buffer (get-buffer candidate)
                           (and (erc-server-buffer-p)
                                (not (erc-server-process-alive)))))
                     (with-current-buffer (get-buffer candidate)
                       (and (string= erc-session-server server)
                            (erc-port-equal erc-session-port port)))))
            (setq buffer-name candidate)))
      ;; if buffer-name is unset, neither candidate worked out for us,
      ;; fallback to the old <N> uniquification method:
      (or buffer-name (generate-new-buffer-name (concat buf-name "/" server))) ))

In GNU Emacs 25.1.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-09-15, modified by Debian built on trouble
Windowing system distributor 'The X.Org Foundation', version 11.0.11902000
System Description:	Debian GNU/Linux 9.3 (stretch)

Configured using:
 'configure --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/lib
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-pop=yes
 --enable-locallisppath=/etc/emacs25:/etc/emacs:/usr/local/share/emacs/25.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/25.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/lib
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-pop=yes
 --enable-locallisppath=/etc/emacs25:/etc/emacs:/usr/local/share/emacs/25.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/25.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --with-x=yes --with-x-toolkit=gtk3
 --with-toolkit-scroll-bars 'CFLAGS=-g -O2
 -fdebug-prefix-map=/build/emacs25-wN2qS3/emacs25-25.1+1=. -fstack-protector-strong
 -Wformat -Werror=format-security -Wall' 'CPPFLAGS=-Wdate-time
 -D_FORTIFY_SOURCE=2' LDFLAGS=-Wl,-z,relro'

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GCONF GSETTINGS
NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11

Important settings:
  value of $LANG: en_US.utf8
  locale-coding-system: utf-8-unix

Major mode: mu4e:main