]> git.eshelyaron.com Git - emacs.git/commitdiff
Avoid mutating default value of erc-server-last-peers
authorF. Jason Park <jp@neverwas.me>
Wed, 6 Jul 2022 07:40:42 +0000 (00:40 -0700)
committerF. Jason Park <jp@neverwas.me>
Wed, 27 Jul 2022 12:19:09 +0000 (05:19 -0700)
* lisp/erc/erc-backend.el (erc-server-last-peers): Leave default as
nil instead of a quoted constant.
(erc-server-connect): Initialize `erc-server-last-peers' to a new
value local to a server buffer.
(erc-message): Operate on server's local `erc-server-last-peers' value
instead of the global default.  Prefer replacing value instead of
mutating CDR to make for easier testing.
(erc-server-PRIVMSG): Create a new `erc-server-last-peers' for easier
testing. (Bug#56449)

lisp/erc/erc-backend.el
test/lisp/erc/erc-tests.el

index 46c96c1a7499a8ee0e8bc4b04a395a560883597a..f83c27dc4e2503f132533ba2afe5e58f13208342 100644 (file)
@@ -230,7 +230,7 @@ current IRC process is still alive.")
 (defvar-local erc-server-lines-sent nil
   "Line counter.")
 
-(defvar-local erc-server-last-peers '(nil . nil)
+(defvar-local erc-server-last-peers nil
   "Last peers used, both sender and receiver.
 Those are used for /MSG destination shortcuts.")
 
@@ -562,7 +562,7 @@ TLS (see `erc-session-client-certificate' for more details)."
         (setq erc-server-last-received-time time))
       (setq erc-server-lines-sent 0)
       ;; last peers (sender and receiver)
-      (setq erc-server-last-peers '(nil . nil)))
+      (setq erc-server-last-peers (cons nil nil)))
     ;; we do our own encoding and decoding
     (when (fboundp 'set-process-coding-system)
       (set-process-coding-system process 'raw-text))
@@ -939,21 +939,20 @@ be used.  If the target is \".\", the last person you've sent a message
 to will be used."
   (cond
    ((string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line)
-    (let ((tgt (match-string 1 line))
-          (s (match-string 2 line)))
+    (let* ((tgt (match-string 1 line))
+           (s (match-string 2 line))
+           (server-buffer (erc-server-buffer))
+           (peers (buffer-local-value 'erc-server-last-peers server-buffer)))
       (erc-log (format "cmd: MSG(%s): [%s] %s" message-command tgt s))
       (cond
        ((string= tgt ",")
-        (if (car erc-server-last-peers)
-            (setq tgt (car erc-server-last-peers))
-          (setq tgt nil)))
+        (setq tgt (car peers)))
        ((string= tgt ".")
-        (if (cdr erc-server-last-peers)
-            (setq tgt (cdr erc-server-last-peers))
-          (setq tgt nil))))
+        (setq tgt (cdr peers))))
       (cond
        (tgt
-        (setcdr erc-server-last-peers tgt)
+        (with-current-buffer server-buffer
+          (setq erc-server-last-peers (cons (car peers) tgt)))
         (erc-server-send (format "%s %s :%s" message-command tgt s)
                          force))
        (t
@@ -1552,7 +1551,7 @@ add things to `%s' instead."
                     (erc-process-ctcp-reply proc parsed nick login host
                                             (match-string 1 msg)))))
          (t
-          (setcar erc-server-last-peers nick)
+          (setq erc-server-last-peers (cons nick (cdr erc-server-last-peers)))
           (setq s (erc-format-privmessage
                    (or fnick nick) msg
                    ;; If buffer is a query buffer,
index 4971d0e194fb33f7f0fb75af5b1f3d29ed6c8727..0f222edacfae7415b940ef10a4cfeccf31e2afbf 100644 (file)
 
           (should-not calls))))))
 
+;; Note: if adding an erc-backend-tests.el, please relocate this there.
+
+(ert-deftest erc-message ()
+  (should-not erc-server-last-peers)
+  (let (server-proc
+        calls
+        erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+    (cl-letf (((symbol-function 'erc-display-message)
+               (lambda (_ _ _ line) (push line calls)))
+              ((symbol-function 'erc-server-send)
+               (lambda (line _) (push line calls)))
+              ((symbol-function 'erc-server-buffer)
+               (lambda () (process-buffer server-proc))))
+      (with-current-buffer (get-buffer-create "ExampleNet")
+        (erc-mode)
+        (setq erc-server-current-nick "tester"
+              server-proc (start-process "sleep" (current-buffer) "sleep" "1")
+              erc-server-process server-proc
+              erc-server-last-peers (cons nil nil)
+              erc-server-users (make-hash-table :test 'equal)
+              erc-network 'ExampleNet)
+        (set-process-query-on-exit-flag erc-server-process nil))
+
+      (with-current-buffer (get-buffer-create "#chan")
+        (erc-mode)
+        (setq erc-server-process (buffer-local-value 'erc-server-process
+                                                     (get-buffer "ExampleNet"))
+              erc-default-recipients '("#chan")
+              erc-channel-users (make-hash-table :test 'equal)
+              erc-network 'ExampleNet)
+        (erc-update-current-channel-member "alice" "alice")
+        (erc-update-current-channel-member "tester" "tester"))
+
+      (with-current-buffer "ExampleNet"
+        (erc-server-PRIVMSG erc-server-process
+                            (make-erc-response
+                             :sender "alice!~u@fsf.org"
+                             :command "PRIVMSG"
+                             :command-args '("#chan" "hi")
+                             :unparsed ":alice!~u@fsf.org PRIVMSG #chan :hi"))
+        (should (equal erc-server-last-peers '("alice")))
+        (should (string-match "<alice>" (pop calls))))
+
+      (with-current-buffer "#chan"
+        (ert-info ("Shortcuts usable in target buffers")
+          (should-not (local-variable-p 'erc-server-last-peers))
+          (should-not erc-server-last-peers)
+          (erc-message "PRIVMSG" ". hi")
+          (should-not erc-server-last-peers)
+          (should (eq 'no-target (pop calls)))
+          (erc-message "PRIVMSG" ", hi")
+          (should-not erc-server-last-peers)
+          (should (string-match "alice :hi" (pop calls)))))
+
+      (with-current-buffer "ExampleNet"
+        (ert-info ("Shortcuts local in server bufs")
+          (should (equal erc-server-last-peers '("alice" . "alice")))
+          (erc-message "PRIVMSG" ", hi")
+          (should (equal erc-server-last-peers '("alice" . "alice")))
+          (should (string-match "PRIVMSG alice :hi" (pop calls)))
+          (setcdr erc-server-last-peers "bob")
+          (erc-message "PRIVMSG" ". hi")
+          (should (equal erc-server-last-peers '("alice" . "bob")))
+          (should (string-match "PRIVMSG bob :hi" (pop calls)))))
+
+      (with-current-buffer "#chan"
+        (ert-info ("Non-shortcuts are local to server buffer")
+          (should-not (local-variable-p 'erc-server-last-peers))
+          (should-not erc-server-last-peers)
+          (erc-message "PRIVMSG" "#chan hola")
+          (should-not erc-server-last-peers)
+          (should-not (default-value 'erc-server-last-peers))
+          (should (equal (buffer-local-value 'erc-server-last-peers
+                                             (get-buffer "ExampleNet"))
+                         '("alice" . "#chan")))
+          (should (string-match "hola" (pop calls))))))
+
+    (should-not erc-server-last-peers)
+    (should-not calls)
+    (kill-buffer "ExampleNet")
+    (kill-buffer "#chan")))
+
 ;;; erc-tests.el ends here