summaryrefslogtreecommitdiff
path: root/lisp/simple.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2020-02-08 22:06:41 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2020-02-08 22:06:41 -0500
commit2645ae1222db1df270276b227e5102884466ecb0 (patch)
tree66d69be733bc18ad37350b9db3346c0cf875dcd0 /lisp/simple.el
parentfe903c5ab7354b97f80ecf1b01ca3ff1027be446 (diff)
downloademacs-2645ae1222db1df270276b227e5102884466ecb0.tar.gz
* lisp/simple.el (undo-redo): New command
(undo--last-change-was-undo-p): New function. * test/lisp/simple-tests.el (simple-tests--exec): New function. (simple-tests--undo): New test.
Diffstat (limited to 'lisp/simple.el')
-rw-r--r--lisp/simple.el24
1 files changed, 24 insertions, 0 deletions
diff --git a/lisp/simple.el b/lisp/simple.el
index 09447900ded..8efba57c4d0 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2662,6 +2662,30 @@ Contrary to `undo', this will not redo a previous undo."
(interactive "*p")
(let ((undo-no-redo t)) (undo arg)))
+(defun undo--last-change-was-undo-p (undo-list)
+ (while (and (consp undo-list) (eq (car undo-list) nil))
+ (setq undo-list (cdr undo-list)))
+ (gethash undo-list undo-equiv-table))
+
+(defun undo-redo (&optional arg)
+ "Undo the last ARG undos."
+ (interactive "*p")
+ (cond
+ ((not (undo--last-change-was-undo-p buffer-undo-list))
+ (user-error "No undo to undo"))
+ (t
+ (let* ((ul buffer-undo-list)
+ (new-ul
+ (let ((undo-in-progress t))
+ (while (and (consp ul) (eq (car ul) nil))
+ (setq ul (cdr ul)))
+ (primitive-undo arg ul)))
+ (new-pul (undo--last-change-was-undo-p new-ul)))
+ (message "Redo%s" (if undo-in-region " in region" ""))
+ (setq this-command 'undo)
+ (setq pending-undo-list new-pul)
+ (setq buffer-undo-list new-ul)))))
+
(defvar undo-in-progress nil
"Non-nil while performing an undo.
Some change-hooks test this variable to do something different.")