[Top][All Lists]

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

bug#16818: Acknowledgement (Undo in region after markers in undo history

From: Stefan
Subject: bug#16818: Acknowledgement (Undo in region after markers in undo history relocated)
Date: Mon, 17 Mar 2014 20:02:43 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

>> The primitive-undo fix should be safe enough for 24.4, so if you
>> want to code this up and install it, feel free.
> I have attached the patch for this, which I'll install if nothing
> comes up from review.

Thanks.  A few comments below.

--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2229,6 +2229,7 @@
         (did-apply nil)
         (next nil))
     (while (> arg 0)
+      (let (del-pos)
       (while (setq next (pop list))     ;Exit inner loop at undo boundary.
         ;; Handle an integer by setting point to that value.
         (pcase next
@@ -2289,6 +2290,7 @@
            (when (let ((apos (abs pos)))
                    (or (< apos (point-min)) (> apos (point-max))))
              (error "Changes to be undone are outside visible portion of 
+             (setq del-pos pos)
            (if (< pos 0)
                  (goto-char (- pos))
@@ -2303,11 +2305,14 @@
              (goto-char pos)))
           ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.
           (`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))
-           (when (marker-buffer marker)
+             (when (and del-pos
+                        (integerp (marker-position marker))
+                        (= del-pos marker)
+                        (marker-buffer marker))
              (set-marker marker
                          (- marker offset)
                          (marker-buffer marker))))
-          (_ (error "Unrecognized entry in undo list %S" next))))
+            (_ (error "Unrecognized entry in undo list %S" next)))))
       (setq arg (1- arg)))
     ;; Make sure an apply entry produces at least one undo entry,
     ;; so the test in `undo' for continuing an undo series

The "move-after" markers will be at (+ del-pos (length inserted-text))
rather than at del-pos.  Also, a lone (MARKER . OFFSET) entry will
arbitrarily use some unrelated earlier del-pos.  Admittedly, such lone
(MARKER . OFFSET) entries should/will never happen, but I'd rather we
catch them and emit a warning than silently do something arbitrary.

IOW, I think we should only change the entry corresponding to a deletion
such that it directly handles all the immediately following
marker-adjustments (it can check them before doing the insertion, hence
using del-pos without having to care about insert-after vs
insert-before).  Then the current handling of marker-adjustments can be
changed to emit a warning.

> @@ -2351,18 +2354,30 @@ If we find an element that crosses an edge of this 
> region,
>  we stop and ignore all further elements."
>    (let ((undo-list-copy (undo-copy-list buffer-undo-list))
>       (undo-list (list nil))
> -     undo-adjusted-markers
> +        ;; The position of a deletion record (TEXT . POSITION) of the
> +        ;; current change group.
> +        ;;
> +        ;; This is used to check that marker adjustmenets are in the
> +        ;; region.  Bug 16818 describes why the marker's position is
> +        ;; not suitable.
> +        del-pos
>       some-rejected
>       undo-elt temp-undo-list delta)
>      (while undo-list-copy
>        (setq undo-elt (car undo-list-copy))
> +      ;; Update del-pos
> +      (if undo-elt
> +          (when (and (consp undo-elt) (stringp (car undo-elt)))
> +            (setq del-pos (cdr undo-elt)))
> +        ;; Undo boundary means new change group, so unset del-pos
> +        (setq del-pos nil))
>        (let ((keep-this
>            (cond ((and (consp undo-elt) (eq (car undo-elt) t))
>                   ;; This is a "was unmodified" element.
>                   ;; Keep it if we have kept everything thus far.
>                   (not some-rejected))
>                  (t
> -                 (undo-elt-in-region undo-elt start end)))))
> +                 (undo-elt-in-region undo-elt start end del-pos)))))
>       (if keep-this
>           (progn
>             (setq end (+ end (cdr (undo-delta undo-elt))))

I'd have the same comment here, but if we emit a warning for sole
marker-adjustments in the "non-region" code, we don't really have to
worry about them here.

But this is also affected by the issue of "move-after" markers where
`del-pos' is not sufficient info since those markers won't be at del-pos
any more if they were at del-pos before we inserted the deleted text.


reply via email to

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