From 781f950edab0509f12e3ec4880690ef6541841ee Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sat, 4 Nov 2023 11:08:22 -0700 Subject: [PATCH] Preserve user markers when inserting ERC date stamps * lisp/erc/erc-stamp.el (erc-stamp--insert-date-stamp-as-phony-message): Ensure existing user markers aren't displaced by date-stamp insertion. * lisp/erc/erc.el (erc--insert-line-function): New function-valued variable for overriding `insert'. (erc-insert-line): Call `erc--insert-line-function', when non-nil, to insert line specially. * test/lisp/erc/erc-scenarios-stamp.el (erc-scenarios-stamp--on-insert-modify): New assertion helper function. (erc-scenarios-stamp--date-mode/left-and-right): New test. (Bug#60936) --- lisp/erc/erc-stamp.el | 1 + lisp/erc/erc.el | 7 ++- test/lisp/erc/erc-scenarios-stamp.el | 65 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index b5224674783..b65c7adf676 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -670,6 +670,7 @@ value of t means the option's value doesn't require trimming.") (let ((erc-stamp--skip t) (erc-insert-modify-hook `(,@erc-insert-modify-hook erc-stamp--propertize-left-date-stamp)) + (erc--insert-line-function #'insert-before-markers) ;; Don't run hooks that aren't expecting a narrowed buffer. (erc-insert-pre-hook nil) (erc-insert-done-hook nil)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index a5457601223..fd57cb9d6a0 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -3083,6 +3083,9 @@ If END is a marker, possibly update its position." (unless (eq end erc-insert-marker) (set-marker end nil))) +(defvar erc--insert-line-function nil + "When non-nil, an alterntive to `insert' for inserting messages.") + (defvar erc--insert-marker nil "Internal override for `erc-insert-marker'.") @@ -3134,7 +3137,9 @@ modification hooks)." (save-restriction (widen) (goto-char insert-position) - (insert string) + (if erc--insert-line-function + (funcall erc--insert-line-function string) + (insert string)) (erc--assert-input-bounds) ;; run insertion hook, with point at restored location (save-restriction diff --git a/test/lisp/erc/erc-scenarios-stamp.el b/test/lisp/erc/erc-scenarios-stamp.el index b98300d04be..49307dd228a 100644 --- a/test/lisp/erc/erc-scenarios-stamp.el +++ b/test/lisp/erc/erc-scenarios-stamp.el @@ -113,4 +113,69 @@ (not (eq 'erc-timestamp (field-at-pos (point)))))) (should (erc--get-inserted-msg-prop 'erc-cmd))))))) +;; This user-owned hook member places a marker on the first message in +;; a buffer. Inserting a date stamp in front of it shouldn't move the +;; marker. +(defun erc-scenarios-stamp--on-insert-modify () + (unless (marker-position erc-scenarios-stamp--user-marker) + (set-marker erc-scenarios-stamp--user-marker (point-min)) + (save-excursion + (goto-char erc-scenarios-stamp--user-marker) + (should (looking-at "Opening")))) + + ;; Sometime after the first message ("Opening connection.."), assert + ;; that the marker we just placed hasn't moved. + (when (erc--check-msg-prop 'erc-cmd 2) + (save-restriction + (widen) + (ert-info ("Date stamp preserves opening user marker") + (goto-char erc-scenarios-stamp--user-marker) + (should-not (eq 'erc-timestamp (field-at-pos (point)))) + (should (looking-at "Opening")) + (should (eq 'unknown (get-text-property (point) 'erc-msg)))))) + + ;; On 003 ("*** This server was created on"), clear state to force a + ;; new date stamp on the next message. + (when (erc--check-msg-prop 'erc-cmd 3) + (setq erc-timestamp-last-inserted-left nil) + (set-marker erc-scenarios-stamp--user-marker erc-insert-marker))) + +(ert-deftest erc-scenarios-stamp--date-mode/left-and-right () + + (should (eq erc-insert-timestamp-function + #'erc-insert-timestamp-left-and-right)) + + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/reconnect") + (dumb-server (erc-d-run "localhost" t 'unexpected-disconnect)) + (port (process-contact dumb-server :service)) + (erc-scenarios-stamp--user-marker (make-marker)) + (erc-server-flood-penalty 0.1) + (erc-modules (if (zerop (random 2)) + (cons 'fill-wrap erc-modules) + erc-modules)) + (expect (erc-d-t-make-expecter)) + (erc-mode-hook + (cons (lambda () + (add-hook 'erc-insert-modify-hook + #'erc-scenarios-stamp--on-insert-modify -99 t)) + erc-mode-hook))) + + (ert-info ("Connect") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :full-name "tester" + :nick "tester") + + (funcall expect 5 "Welcome to the foonet") + (funcall expect 5 "*** AWAYLEN=390") + + (ert-info ("Date stamp preserves other user marker") + (goto-char erc-scenarios-stamp--user-marker) + (should-not (eq 'erc-timestamp (field-at-pos (point)))) + (should (looking-at (rx "*** irc.foonet.org oragono"))) + (should (eq 's004 (get-text-property (point) 'erc-msg)))) + + (funcall expect 5 "This server is in debug mode"))))) + ;;; erc-scenarios-stamp.el ends here -- 2.39.2