commit 5cf79a19dac5187b6e8f4f6c3798d0f348eff89c Author: Campbell Barton Date: Fri Oct 29 12:33:29 2021 +1100 Add a version of atomic-change-group that amalgamates undo steps diff --git a/lisp/subr.el b/lisp/subr.el index 39676249cd..4d2ca0b953 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3490,15 +3490,8 @@ y-or-n-p ;;; Atomic change groups. -(defmacro atomic-change-group (&rest body) - "Like `progn' but perform BODY as an atomic change group. -This means that if BODY exits abnormally, -all of its changes to the current buffer are undone. -This works regardless of whether undo is enabled in the buffer. - -This mechanism is transparent to ordinary use of undo; -if undo is enabled in the buffer and BODY succeeds, the -user can undo the change normally." +(defmacro atomic-change-group-1 (undo-amalgamate &rest body) + "Implementation of `atomic-change-group' & `atomic-change-group-amalgamate'." (declare (indent 0) (debug t)) (let ((handle (make-symbol "--change-group-handle--")) (success (make-symbol "--change-group-success--"))) @@ -3519,9 +3512,28 @@ atomic-change-group ;; Either of these functions will disable undo ;; if it was disabled before. (if ,success - (accept-change-group ,handle) + (progn + (accept-change-group ,handle) + (when ,undo-amalgamate + (undo-amalgamate-change-group ,handle))) (cancel-change-group ,handle)))))) +(defmacro atomic-change-group (&rest body) + "Like `progn' but perform BODY as an atomic change group. +This means that if BODY exits abnormally, +all of its changes to the current buffer are undone. +This works regardless of whether undo is enabled in the buffer. + +This mechanism is transparent to ordinary use of undo; +if undo is enabled in the buffer and BODY succeeds, the +user can undo the change normally." + `(atomic-change-group-1 nil ,@body)) + +(defmacro atomic-change-group-undo-amalgamate (&rest body) + "A version of `atomic-change-group' that amalgamates +the change groups undo data." + `(atomic-change-group-1 t ,@body)) + (defun prepare-change-group (&optional buffer) "Return a handle for the current buffer's state, for a change group. If you specify BUFFER, make a handle for BUFFER's state instead.