From 2111af98c9ae2cba9cdfbd0abbd27f078cb633ff Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sun, 24 Nov 2024 15:30:02 -0800 Subject: [PATCH] Clear buffer-undo-list after sending input in ERC * lisp/erc/erc.el (erc-insert-line): Assume `erc-insert-marker' points somewhere. (erc-send-current-line): Set `buffer-undo-list' to nil because it should only record editing changes in the prompt area, which has just been cleared. ERC did this via `erc-display-prompt' prior to 5.6, but it now leaves the prompt alone by default. * test/lisp/erc/erc-tests.el (erc-update-undo-list): New test. (Bug#74518) (cherry picked from commit e0d2c6f20f01366c41ba33d663a2b319dd9b7ab1) --- lisp/erc/erc.el | 10 ++--- test/lisp/erc/erc-tests.el | 79 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index e6cc50f1b94..bd2cf57d5e9 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -3515,8 +3515,7 @@ modification hooks)." (add-text-properties (point-min) (1+ (point-min)) props))) (erc--refresh-prompt))))) (run-hooks 'erc-insert-done-hook) - (erc-update-undo-list (- (or (marker-position (or erc--insert-marker - erc-insert-marker)) + (erc-update-undo-list (- (or erc--insert-marker erc-insert-marker (point-max)) insert-position)))))) @@ -8199,10 +8198,9 @@ ERC prints them as a single message joined by newlines.") ;; Fix the buffer if the command didn't kill it (when (buffer-live-p old-buf) (with-current-buffer old-buf - (save-restriction - (widen) - (let ((buffer-modified (buffer-modified-p))) - (set-buffer-modified-p buffer-modified)))))) + (setq buffer-undo-list nil) + ;; `set-buffer-modified-p' used to do this here. + (force-mode-line-update)))) ;; Only when last hook has been run... (run-hook-with-args 'erc-send-completed-hook str))) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index eddb3a5b2c8..7a4df04794e 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -2915,6 +2915,85 @@ (should (equal (erc-tests--format-my-nick "oh my") expect)) (should (equal (erc--format-speaker-input-message "oh my") expect)))) +(ert-deftest erc-update-undo-list () + ;; Remove `stamp' so this can run in any locale. Alternatively, we + ;; could explicitly enable it and bind its format options to strings + ;; that lack specifiers (perhaps in a separate test). + (let ((erc-modules (remq 'stamp erc-modules)) + (erc-mode-hook erc-mode-hook) + (erc-insert-modify-hook erc-insert-modify-hook) + (erc-send-modify-hook erc-send-modify-hook) + (inhibit-message noninteractive) + marker) + + (erc-stamp-mode -1) + (erc-tests-common-make-server-buf) + (setq erc-server-current-nick "tester") + + (with-current-buffer (erc--open-target "#chan") + ;; Add some filler to simulate more realistic values. + (erc-tests-common-simulate-line + ":irc.foonet.org 353 tester = #chan :bob tester alice") + (erc-tests-common-simulate-line + ":irc.foonet.org 366 tester #chan :End of NAMES list") + (should (erc-get-server-user "bob")) + + (goto-char (point-max)) + (should (= (point) 45)) + + ;; Populate undo list with contrived values. + (let ((kill-ring (list "abc")) + interprogram-paste-function) + (yank)) + (push nil buffer-undo-list) + (push (point-max) buffer-undo-list) + (setq marker (point-marker)) + (put-text-property 46 47 'face 'warning) + (call-interactively #'delete-backward-char 1) + (push nil buffer-undo-list) + (should (= (point) 47)) + (should (equal buffer-undo-list `(nil + ("c" . -47) + (,marker . -1) + (nil face nil 46 . 47) + 48 + nil + (45 . 48)))) + + ;; The first char after the prompt is at buffer pos 45. + (should (= 40 (- 45 (length (erc-prompt))) erc-insert-marker)) + + ;; A new message arrives, growing the buffer by 11 chars. + (erc-tests-common-simulate-privmsg "bob" "test") + (should (equal (buffer-substring 40 erc-insert-marker) " test\n")) + (should (= (point-max) 58)) + (should (= 11 (length " test\n") (- (point) 47))) + + ;; The list remains unchanged relative to the end of the buffer. + (should (equal buffer-undo-list `(nil + ("c" . -58) + (,marker . -1) + (nil face nil 57 . 58) + 59 + nil + (56 . 59)))) + + ;; Undo behavior works as expected. + (undo nil) + (should (erc-tests-common-equal-with-props + (buffer-substring erc-input-marker (point-max)) + #("abc" 1 2 (face nil)))) + (should (equal (take 4 buffer-undo-list) + `((nil face warning 57 . 58) + (58 . 59) + nil + ("c" . -58)))) + (undo 2) + (should (string-empty-p (erc-user-input))))) + + (when noninteractive + (erc-tests-common-kill-buffers))) + (ert-deftest erc--route-insertion () (erc-tests-common-prep-for-insertion) (erc-tests-common-init-server-proc "sleep" "1") -- 2.39.2