emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 7b8322f628 2/3: Use correct buffer for local-module vars in erc


From: F. Jason Park
Subject: emacs-29 7b8322f628 2/3: Use correct buffer for local-module vars in erc-open
Date: Tue, 17 Jan 2023 09:11:17 -0500 (EST)

branch: emacs-29
commit 7b8322f6285702faf5da0824b9b195619da9c698
Author: F. Jason Park <jp@neverwas.me>
Commit: F. Jason Park <jp@neverwas.me>

    Use correct buffer for local-module vars in erc-open
    
    * lisp/erc/erc.el (erc--target-priors): New internal variable to do
    for target buffers what `erc--server-reconnecting' does for server
    buffers.
    (erc-open): Source the state of a local module's mode variable from
    its actual buffer rather than its server buffer.  Additionally, make
    all local variables from a prior session available to
    module-activation functions and `erc-mode' hooks, even when
    `erc-reuse-buffers' is nil.  This bug arrived with the introduction of
    "local-modules" (bug#57955).
    
    * test/lisp/erc/erc-scenarios-base-local-modules.el
    (erc-scenarios-base-local-modules--toggle-helpers): Remove useless
    `with-current-buffer'.
    (erc-scenarios-base-local-modules--local-var, erc--phony-sblm--enable,
    erc--phony-sblm--disable, erc--phony-sblm--mode): Add fake local
    module and data var for test scenario.
    (erc-scenarios-base-local-modules--var-persistence) Add slightly hacky
    test case with promise to improve later when splitting the file.
---
 lisp/erc/erc.el                                   |  15 +++-
 test/lisp/erc/erc-scenarios-base-local-modules.el | 100 ++++++++++++++++++++--
 2 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index ba7db15cf8..e7f81f24ac 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -1305,6 +1305,14 @@ See also `erc-show-my-nick'."
 
 (defvar-local erc-dbuf nil)
 
+;; See comments in `erc-scenarios-base-local-modules' explaining why
+;; this is insufficient as a public interface.
+
+(defvar erc--target-priors nil
+  "Analogous to `erc--server-reconnecting' but for target buffers.
+Bound to local variables from an existing (logical) session's
+buffer during local-module setup and `erc-mode-hook' activation.")
+
 (defun erc--target-from-string (string)
   "Construct an `erc--target' variant from STRING."
   (funcall (if (erc-channel-p string)
@@ -1985,7 +1993,9 @@ Returns the buffer for the given server or channel."
   (let* ((target (and channel (erc--target-from-string channel)))
          (buffer (erc-get-buffer-create server port nil target id))
          (old-buffer (current-buffer))
-         (old-vars (and target (buffer-local-variables)))
+         (erc--target-priors (and target ; buf from prior session
+                                  (buffer-local-value 'erc--target buffer)
+                                  (buffer-local-variables buffer)))
          (old-recon-count erc-server-reconnect-count)
          (old-point nil)
          (delayed-modules nil)
@@ -1998,7 +2008,8 @@ Returns the buffer for the given server or channel."
     (setq old-point (point))
     (setq delayed-modules
           (erc--merge-local-modes (erc--update-modules)
-                                  (or erc--server-reconnecting old-vars)))
+                                  (or erc--server-reconnecting
+                                      erc--target-priors)))
 
     (delay-mode-hooks (erc-mode))
 
diff --git a/test/lisp/erc/erc-scenarios-base-local-modules.el 
b/test/lisp/erc/erc-scenarios-base-local-modules.el
index d4001df45d..916d105779 100644
--- a/test/lisp/erc/erc-scenarios-base-local-modules.el
+++ b/test/lisp/erc/erc-scenarios-base-local-modules.el
@@ -19,8 +19,17 @@
 
 ;;; Commentary:
 
-;; These tests all use `sasl' because, as of ERC 5.5, it's the one
-;; and only local module.
+;; A local module doubles as a minor mode whose mode variable and
+;; associated local data can withstand service disruptions.
+;; Unfortunately, the current implementation is too unwieldy to be
+;; made public because it doesn't perform any of the boiler plate
+;; needed to save and restore buffer-local and "network-local" copies
+;; of user options.  Ultimately, a user-friendly framework must fill
+;; this void if third-party local modules are ever to become
+;; practical.
+;;
+;; The following tests all use `sasl' because, as of ERC 5.5, it's the
+;; only local module.
 
 ;;; Code:
 
@@ -206,7 +215,7 @@
         (erc-cmd-QUIT "")
         (funcall expect 10 "finished")))
 
-    (ert-info ("Disabling works from a target buffer.")
+    (ert-info ("Disabling works from a target buffer")
       (with-current-buffer "#chan"
         (should erc-sasl-mode)
         (call-interactively #'erc-sasl-disable)
@@ -214,10 +223,9 @@
         (should (local-variable-p 'erc-sasl-mode))
         (should-not (buffer-local-value 'erc-sasl-mode (get-buffer "foonet")))
         (erc-cmd-RECONNECT)
-        (with-current-buffer "#chan"
-          (funcall expect 10 "Some enigma, some riddle")
-          (should-not erc-sasl-mode) ; regression
-          (should (local-variable-p 'erc-sasl-mode))))
+        (funcall expect 10 "Some enigma, some riddle")
+        (should-not erc-sasl-mode) ; regression
+        (should (local-variable-p 'erc-sasl-mode)))
 
       (with-current-buffer "foonet"
         (should (local-variable-p 'erc-sasl-mode))
@@ -239,4 +247,82 @@
         (should erc-sasl-mode)
         (funcall expect 10 "User modes for tester")))))
 
+(defvar-local erc-scenarios-base-local-modules--local-var nil)
+
+(define-erc-module -phony-sblm- nil
+  "Test module for `erc-scenarios-base-local-modules--var-persistence'."
+  ((when-let ((vars (or erc--server-reconnecting erc--target-priors)))
+     (should (assq 'erc--phony-sblm--mode vars))
+     (setq erc-scenarios-base-local-modules--local-var
+           (alist-get 'erc-scenarios-base-local-modules--local-var vars)))
+   (setq erc-scenarios-base-local-modules--local-var
+         (or erc-scenarios-base-local-modules--local-var
+             (if erc--target 100 0))))
+  ((kill-local-variable 'erc-scenarios-base-local-modules--local-var))
+  'local)
+
+;; Note: this file has grown too expensive (time-wise) and must be
+;; split up.  When that happens, this test should be rewritten without
+;; any time-saving hacks, namely, server-initiated JOINs and an
+;; absence of QUITs.  (That said, three connections in under 2 seconds
+;; is pretty nice.)
+
+(ert-deftest erc-scenarios-base-local-modules--var-persistence ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/reconnect")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'options 'options 'options))
+       (port (process-contact dumb-server :service))
+       (erc-modules (cons '-phony-sblm- (remq 'autojoin erc-modules)))
+       (expect (erc-d-t-make-expecter))
+       (server-buffer-name (format "127.0.0.1:%d" port)))
+
+    (ert-info ("Initial authentication succeeds as expected")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) server-buffer-name)))
+
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "FooNet"))
+        (funcall expect 10 "This server is in debug mode")
+        (should erc--phony-sblm--mode)
+        (should (eql erc-scenarios-base-local-modules--local-var 0))
+        (setq erc-scenarios-base-local-modules--local-var 1)))
+
+    (ert-info ("Save module's local var in target buffer")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+        (should (eql erc-scenarios-base-local-modules--local-var 100))
+        (setq erc-scenarios-base-local-modules--local-var 101)
+        (funcall expect 20 "welcome")))
+
+    (with-current-buffer "FooNet" (funcall expect 20 "terminated"))
+
+    (ert-info ("Vars reused when mode was left enabled")
+      (with-current-buffer "#chan"
+        (erc-cmd-RECONNECT)
+        (funcall expect 20 "welcome")
+        (should (eql erc-scenarios-base-local-modules--local-var 101))
+        (erc--phony-sblm--mode -1))
+
+      (with-current-buffer "FooNet"
+        (funcall expect 10 "User modes for tester")
+        (should (eql erc-scenarios-base-local-modules--local-var 1))))
+
+    (with-current-buffer "FooNet" (funcall expect 20 "terminated"))
+
+    (ert-info ("Local binding gone when mode disabled in target")
+      (with-current-buffer "#chan"
+        (erc-cmd-RECONNECT)
+        (funcall expect 20 "welcome")
+        (should-not erc--phony-sblm--mode)
+        (should-not erc-scenarios-base-local-modules--local-var))
+
+      ;; But value retained in server buffer, where mode is active.
+      (with-current-buffer "FooNet"
+        (funcall expect 10 "User modes for tester")
+        (should (eql erc-scenarios-base-local-modules--local-var 1))))))
+
 ;;; erc-scenarios-local-modules.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]