]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/subr.el (cancel-change-group): Reset cell in case of error
authorStefan Monnier <monnier@iro.umontreal.ca>
Tue, 26 Jul 2016 17:14:50 +0000 (13:14 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Tue, 26 Jul 2016 17:14:50 +0000 (13:14 -0400)
Since the setcdr/setcdr is supposed to be temporary, use unwind-protect
to make sure we properly undo the temporary change even in case of error.

lisp/subr.el

index 937a05068263b00d56b0e878758a1a815301d0cc..2c0be204e0ab606e55d54d0d72736ab4cecc7a4f 100644 (file)
@@ -2535,26 +2535,27 @@ This finishes the change group by reverting all of its changes."
        ;; Widen buffer temporarily so if the buffer was narrowed within
        ;; the body of `atomic-change-group' all changes can be undone.
        (widen)
-       (let ((old-car
-              (if (consp elt) (car elt)))
-             (old-cdr
-              (if (consp elt) (cdr elt))))
-         ;; Temporarily truncate the undo log at ELT.
-         (when (consp elt)
-           (setcar elt nil) (setcdr elt nil))
-         (unless (eq last-command 'undo) (undo-start))
-         ;; Make sure there's no confusion.
-         (when (and (consp elt) (not (eq elt (last pending-undo-list))))
-           (error "Undoing to some unrelated state"))
-         ;; Undo it all.
-         (save-excursion
-           (while (listp pending-undo-list) (undo-more 1)))
-         ;; Reset the modified cons cell ELT to its original content.
-         (when (consp elt)
-           (setcar elt old-car)
-           (setcdr elt old-cdr))
-         ;; Revert the undo info to what it was when we grabbed the state.
-         (setq buffer-undo-list elt))))))
+       (let ((old-car (car-safe elt))
+             (old-cdr (cdr-safe elt)))
+          (unwind-protect
+              (progn
+                ;; Temporarily truncate the undo log at ELT.
+                (when (consp elt)
+                  (setcar elt nil) (setcdr elt nil))
+                (unless (eq last-command 'undo) (undo-start))
+                ;; Make sure there's no confusion.
+                (when (and (consp elt) (not (eq elt (last pending-undo-list))))
+                  (error "Undoing to some unrelated state"))
+                ;; Undo it all.
+                (save-excursion
+                  (while (listp pending-undo-list) (undo-more 1)))
+                ;; Revert the undo info to what it was when we grabbed
+                ;; the state.
+                (setq buffer-undo-list elt))
+            ;; Reset the modified cons cell ELT to its original content.
+            (when (consp elt)
+              (setcar elt old-car)
+              (setcdr elt old-cdr))))))))
 \f
 ;;;; Display-related functions.