commit 2964fa126a059bb6f610c43fd8bcf1e700a3f107 Author: Campbell Barton Date: Mon Nov 8 16:33:39 2021 +1100 Add 'with-undo-amalgamate' macro This allows commands to be made without adding undo-barriers, e.g. kmacro-exec-ring-item. diff --git a/lisp/subr.el b/lisp/subr.el index f6dbd00532..73b799c65b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3542,6 +3542,29 @@ atomic-change-group (accept-change-group ,handle) (cancel-change-group ,handle)))))) +(defmacro with-undo-amalgamate (&rest body) + "Like `progn' but perform BODY with amalgamated undo barriers. + +This allows multiple operations to be undone in a single step. +When undo is disabled this behaves like `progn'." + (declare (indent 0) (debug t)) + (let ((handle (make-symbol "--change-group-handle--"))) + `(let ((,handle (prepare-change-group)) + ;; Don't truncate any undo data in the middle of this. + ;; This guarantees the resulting undo step is complete, + ;; so the user can't undo into an intermediate step + ;; performed within the body of this macro. + (undo-outer-limit nil) + (undo-limit most-positive-fixnum) + (undo-strong-limit most-positive-fixnum)) + (unwind-protect + (progn + (activate-change-group ,handle) + ,@body) + (progn + (accept-change-group ,handle) + (undo-amalgamate-change-group ,handle)))))) + (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.