branch: scratch/proof-general commit ef92861928da68f777ef6c583d18e581e4e9ffb1 Author: Stefan Monnier <monn...@iro.umontreal.ca> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
Try and fix Issue #800 `next-undo-elt` incorrectly skipped `apply` elements, and moreover Emacs's own `undo-delta` does not handle such elements correctly either. Hopefully `undo-delta` will be fixed in Emacs-31, but in the mean time, use our own function instead. Also fix `next-undo-elt` by making it use `undo-delta` instead of re-implementing part of it. Give it a proper namespace prefix while we're at it. * generic/pg-user.el (pg--undo-delta): New function. (pg-protected-undo-1): Use it. (pg--next-undo-elt): Rename from `next-undo-elt`. Use `pg--undo-delta`. --- generic/pg-user.el | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/generic/pg-user.el b/generic/pg-user.el index 07ff560fba..b47f770cab 100644 --- a/generic/pg-user.el +++ b/generic/pg-user.el @@ -3,7 +3,7 @@ ;; This file is part of Proof General. ;; Portions © Copyright 1994-2012 David Aspinall and University of Edinburgh -;; Portions © Copyright 2003-2019 Free Software Foundation, Inc. +;; Portions © Copyright 2003-2024 Free Software Foundation, Inc. ;; Portions © Copyright 2001-2017 Pierre Courtieu ;; Portions © Copyright 2010, 2016 Erik Martin-Dorel ;; Portions © Copyright 2011-2013, 2016-2017 Hendrik Tews @@ -1569,7 +1569,7 @@ removed if it matches the last item in the ring." ;; `buffer-undo-list' in `proof-set-queue-endpoints'. ;; ;; Improved version due to Erik Martin-Dorel. Uses auxiliary -;; functions `pg-protected-undo-1' and `next-undo-elt' +;; functions `pg-protected-undo-1' and `pg--next-undo-elt' ;; (define-key proof-mode-map [remap undo] 'pg-protected-undo) @@ -1609,10 +1609,19 @@ the locked region." (setq last-command 'undo) ; need for this assignment meanwhile (cl-decf repeat))))) +(defalias 'pg--undo-delta + (if (equal '(13 . 21) (undo-delta '(apply 21 13 57 fun arg1))) ;Emacs-31 + #'undo-delta + (lambda (elt) + (pcase elt + ((and `(apply ,delta ,beg . ,_) (guard (integerp delta))) + (cons beg delta)) + (_ (undo-delta elt)))))) + (defun pg-protected-undo-1 (arg) "This function is intended to be called by `pg-protected-undo'. -The flag ARG is passed to functions `undo' and `next-undo-elt'. +The flag ARG is passed to functions `undo' and `pg--next-undo-elt'. It should be a non-numeric value saying whether an undo-in-region behavior is expected." ;; Note that if ARG is non-nil, (> (region-end) (region-beginning)) must hold, @@ -1621,8 +1630,8 @@ behavior is expected." (if (or (not proof-locked-span) (equal (proof-queue-or-locked-end) (point-min))) ; required test (undo arg) - (let* ((next (next-undo-elt arg)) - (delta (undo-delta next)) ; can be '(0 . 0) if next is nil + (let* ((next (pg--next-undo-elt arg)) + (delta (pg--undo-delta next)) ; can be '(0 . 0) if next is nil (beg (car delta)) (end (max beg (- beg (cdr delta))))) ; Key computation (when (and next (> beg 0) ; the "next undo elt" exists @@ -1640,7 +1649,7 @@ behavior is expected." "Cannot undo without retracting to the appropriate position"))) (undo arg)))) -(defun next-undo-elt (arg) +(defun pg--next-undo-elt (arg) "Return the undo element that will be processed on next undo/redo. Assume the undo-in-region behavior will apply if ARG is non-nil." (let ((undo-list (if arg ; handle "undo in region" @@ -1650,10 +1659,7 @@ Assume the undo-in-region behavior will apply if ARG is non-nil." (if (or (null undo-list) (equal undo-list (list nil))) nil ; there is clearly no undo elt (while (and undo-list ; to ensure it will terminate - (let ((elt (car undo-list))) - (not (and (consp elt) - (or (stringp (car elt)) - (integerp (car elt))))))) + (not (equal '(0 . 0) (pg--undo-delta (car undo-list))))) (setq undo-list (cdr undo-list))) ; get the last undo record (if (and (eq last-command 'undo) (or (eq pending-undo-list t)