(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.
This commit is contained in:
Stefan Monnier 2024-04-07 14:16:38 -04:00
parent 8f93cba324
commit 63588775fc
2 changed files with 75 additions and 1 deletions

View file

@ -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;

View file

@ -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