]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/subr.el (with-undo-amalgamate): New macro
authorCampbell Barton <ideasman42@gmail.com>
Mon, 8 Nov 2021 05:33:39 +0000 (16:33 +1100)
committerStefan Monnier <monnier@iro.umontreal.ca>
Mon, 8 Nov 2021 13:34:52 +0000 (08:34 -0500)
This allows commands to be made without adding undo-barriers, e.g.
kmacro-exec-ring-item.

doc/lispref/text.texi
etc/NEWS
lisp/subr.el

index fa1135b8026cd4210da015830104999ca45cf5e5..937680c200d1e06291d9bb7a59a687516e979d34 100644 (file)
@@ -1506,6 +1506,11 @@ continuing to undo.
 This function does not bind @code{undo-in-progress}.
 @end defun
 
+@defmac with-undo-amalgamate body@dots{}
+This macro removes all the undo boundaries inserted during the
+execution of @var{body} so that it can be undone as a single step.
+@end defmac
+
 Some commands leave the region active after execution in such a way that
 it interferes with selective undo of that command.  To make @code{undo}
 ignore the active region when invoked immediately after such a command,
index a297948a11a273799c77a1b42140f1499cba9956..874af33c7526944b3994dd2efc4f5685011d6856 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -598,6 +598,10 @@ Use 'exif-parse-file' and 'exif-field' instead.
 \f
 * Lisp Changes in Emacs 29.1
 
++++
+*** New macro 'with-undo-amalgamate'
+It records a particular sequence of operations as a single undo step
+
 +++
 *** New command 'yank-media'.
 This command supports yanking non-plain-text media like images and
index f6dbd00532e6f516892d8c4aa5dcec36854fab8d..5a5842d4287a41daec7eb15a4b4b39f7263ab921 100644 (file)
@@ -3542,6 +3542,29 @@ user can undo the change normally."
             (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,
+           ;; otherwise Emacs might truncate part of the resulting
+           ;; undo step: we want to mimic the behavior we'd get if the
+           ;; undo-boundaries were never added in the first place.
+           (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.