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.
This commit is contained in:
parent
7b13422298
commit
7b8322f628
2 changed files with 106 additions and 9 deletions
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue