Subject: Re: bug#19363: Acknowledgement (24.4.1; Notifications can make ERC unusable)

From: Dima Kogan <[email-masked]>
Date: Wed, 31 Dec 2014 07:47:24 -0800

Here's a solution to THIS bug, for real this time. I'm attaching a
tested-working patch. I'm no longer sure this is a regression since it's
very sensitive to load order. In emacs 24.3 if ERC is byte-compiled then
the bug manifests, but if it isn't then it works ok. In any case, the
patch solves the issue regardless.

To reiterate, ERC works if you start emacs with no init file, and then
evaluate

  (require 'erc)
  (require 'erc-desktop-notifications)
  (erc-notifications-enable)

However ERC does NOT work if you start with just this in the init file:

  (eval-after-load 'erc
    '(progn
       (require 'erc-desktop-notifications)
       (erc-notifications-enable)
       ))

The issue is that in the working case, the value of
erc-server-PRIVMSG-functions ends up as

  (erc-notifications-PRIVMSG erc-auto-query erc-server-PRIVMSG)

and in the broken case as

  (erc-auto-query erc-notifications-PRIVMSG)

erc-server-PRIVMSG is important, so ERC does not work correctly if it is
missing. This missing element is normally added in

 erc-backend.el by

 (define-erc-response-handler (PRIVMSG NOTICE) ...
    which is a macro. In the macro, the significant line is
   (defvar ,hook-name ',fn-name ,(format hook-doc name))

If we have some (eval-after-load 'erc ...) stuff then by the time this
(defvar) is evaluated, the list may already have a value, so the defvar
then does NOT add its value to the list. The patch explicitly changes
the (defvar list default) idiom to
(defvar list nil) (add-to-list 'list default) and thus the default value
always appears in the list.

>From 28bc9430ce6342d210e986586af7b6f12e103043 Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email-masked]>
Date: Wed, 31 Dec 2014 08:13:57 -0800
Subject: [PATCH] ERC no longer gets confused by (eval-after-load 'erc ...)

ERC was initializing one of its lists with (defvar list default).  If
the list already had a value due to (eval-after-load 'erc ...) for
instance, then (defvar) would see an initialized variable, and would NOT
add the default value to the list.  This was breaking things.  This
patch changes the above defvar idiom to

 (defvar list nil)
 (add-to-list 'list default)

This way the default value is added to the list unconditionally

Closes: #19363
---
 lisp/erc/erc-backend.el | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index fa95d7e..43e56c0 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -1179,8 +1179,11 @@ add things to `%s' instead."
           (cl-loop for alias in aliases
                    collect (intern (format "erc-server-%s-functions" alias)))))
     `(prog2
-         ;; Normal hook variable.
-         (defvar ,hook-name ',fn-name ,(format hook-doc name))
+         ;; Normal hook variable.  The variable may already have a
+         ;; value at this point, so I default to nil, and (add-hook)
+         ;; unconditionally
+         (defvar ,hook-name nil ,(format hook-doc name))
+         (add-to-list ',hook-name ',fn-name)
          ;; Handler function
          (defun ,fn-name (proc parsed)
            ,fn-doc
-- 
2.1.3