emacs-diffs
[Top][All Lists]
Advanced

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

master 5861b8d: * lisp/subr.el (with-undo-amalgamate): New macro


From: Stefan Monnier
Subject: master 5861b8d: * lisp/subr.el (with-undo-amalgamate): New macro
Date: Mon, 8 Nov 2021 08:40:22 -0500 (EST)

branch: master
commit 5861b8d027382ecbd4c0d3dffc283b8ac95b5692
Author: Campbell Barton <ideasman42@gmail.com>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * lisp/subr.el (with-undo-amalgamate): New macro
    
    This allows commands to be made without adding undo-barriers, e.g.
    kmacro-exec-ring-item.
---
 doc/lispref/text.texi |  5 +++++
 etc/NEWS              |  4 ++++
 lisp/subr.el          | 23 +++++++++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index fa1135b..937680c 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -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,
diff --git a/etc/NEWS b/etc/NEWS
index a297948..874af33 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -599,6 +599,10 @@ Use 'exif-parse-file' and 'exif-field' instead.
 * 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
 HTML from other applications into Emacs.  It is only supported in
diff --git a/lisp/subr.el b/lisp/subr.el
index f6dbd00..5a5842d 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -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.



reply via email to

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