emacs-diffs
[Top][All Lists]
Advanced

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

master 63588775fcb: (Freplace_match): Fix bug#65451


From: Stefan Monnier
Subject: master 63588775fcb: (Freplace_match): Fix bug#65451
Date: Sun, 7 Apr 2024 14:16:48 -0400 (EDT)

branch: master
commit 63588775fcb64e4fd88a97e0882aae38c9f5fb1c
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    (Freplace_match): Fix bug#65451
    
    * src/search.c (Freplace_match): For ordering of *-change-functions.
    
    * test/src/editfns-tests.el
    (editfns-tests--before/after-change-functions): New test.
    (sanity-check--message, sanity-check-change-functions-error)
    (sanity-check-change-functions-check-size)
    (sanity-check-change-functions-before)
    (sanity-check-change-functions-after): New functions.
    (sanity-check--verbose, sanity-check-change-functions-beg)
    (sanity-check-change-functions-end)
    (sanity-check-change-functions-buffer-size)
    (sanity-check-change-functions-errors): New vars.
---
 src/search.c              |  2 +-
 test/src/editfns-tests.el | 74 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/search.c b/src/search.c
index f2d1f1f5449..b092d5b7fef 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2759,6 +2759,7 @@ since only regular expressions have distinguished 
subexpressions.  */)
 
   /* Replace the old text with the new in the cleanest possible way.  */
   replace_range (sub_start, sub_end, newtext, 1, 0, 1, true, true);
+  signal_after_change (sub_start, sub_end - sub_start, SCHARS (newtext));
 
   if (case_action == all_caps)
     Fupcase_region (make_fixnum (search_regs.start[sub]),
@@ -2783,7 +2784,6 @@ since only regular expressions have distinguished 
subexpressions.  */)
   /* Now move point "officially" to the end of the inserted replacement.  */
   move_if_not_intangible (newpoint);
 
-  signal_after_change (sub_start, sub_end - sub_start, SCHARS (newtext));
   update_compositions (sub_start, newpoint, CHECK_BORDER);
 
   return Qnil;
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index b3b7da65ad3..a14a5f90b65 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -426,4 +426,78 @@
     (should (= (field-beginning) 7))
     (should (= (field-end) (point-max)))))
 
+;;; Try and catch `*-changes-functions' bugs!
+
+(defvar sanity-check--verbose nil)
+(defun sanity-check--message (&rest args)
+  (if sanity-check--verbose (apply #'message args)))
+
+(defvar-local sanity-check-change-functions-beg 0)
+(defvar-local sanity-check-change-functions-end 0)
+(defvar-local sanity-check-change-functions-buffer-size nil)
+(defvar sanity-check-change-functions-errors nil)
+
+(defun sanity-check-change-functions-error (description &rest args)
+  (push (apply #'format description args)
+        sanity-check-change-functions-errors))
+
+(defun sanity-check-change-functions-check-size ()
+  (sanity-check--message "Size  : %S == %S"
+                         sanity-check-change-functions-buffer-size
+                         (buffer-size))
+  (cond
+   ((null sanity-check-change-functions-buffer-size)
+    (setq sanity-check-change-functions-buffer-size (buffer-size)))
+   ((equal sanity-check-change-functions-buffer-size (buffer-size)) nil)
+   (t
+    (sanity-check-change-functions-error
+     "buffer-size %S == %S"
+     (buffer-size) sanity-check-change-functions-buffer-size)
+    (setq sanity-check-change-functions-buffer-size (buffer-size)))))
+
+(defun sanity-check-change-functions-before (beg end)
+  (sanity-check--message "Before: %S %S" beg end)
+  (unless (<= (point-min) beg end (point-max))
+    (sanity-check-change-functions-error
+     "Position bounds: %S <= %S <= %S <= %S"
+     (point-min) beg end (point-max)))
+  (sanity-check-change-functions-check-size)
+  (setq sanity-check-change-functions-beg beg)
+  (setq sanity-check-change-functions-end end))
+
+(defun sanity-check-change-functions-after (beg end len)
+  (sanity-check--message "After : %S %S (%S)" beg end len)
+  (unless (<= (point-min) beg end (point-max))
+    (sanity-check-change-functions-error
+     "Position bounds: %S <= %S <= %S <= %S"
+     (point-min) beg end (point-max)))
+  (unless (>= len 0)
+    (sanity-check-change-functions-error "len: %S >= 0" len))
+  (let ((bend (+ beg len)))
+    (unless (<= sanity-check-change-functions-beg
+                beg bend
+                sanity-check-change-functions-end)
+      (sanity-check-change-functions-error
+       "After covered by before: %S <= %S <= %S <= %S"
+       sanity-check-change-functions-beg beg bend
+       sanity-check-change-functions-end)))
+  (let ((offset (- end beg len)))
+    (setq sanity-check-change-functions-end
+          (+ sanity-check-change-functions-end offset))
+    (setq sanity-check-change-functions-buffer-size
+          (+ sanity-check-change-functions-buffer-size offset)))
+  (sanity-check-change-functions-check-size))
+
+(ert-deftest editfns-tests--before/after-change-functions ()
+  (with-temp-buffer
+    (add-hook 'before-change-functions
+              #'sanity-check-change-functions-before nil t)
+    (add-hook 'after-change-functions
+              #'sanity-check-change-functions-after nil t)
+
+    ;; Bug#65451
+    (insert "utf-8-unix\n\nUTF")
+    (call-interactively 'dabbrev-expand)
+    (should (null sanity-check-change-functions-errors))))
+
 ;;; editfns-tests.el ends here



reply via email to

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