emacs-devel
[Top][All Lists]
Advanced

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

Re: undo after repeatedly calling 'repeat' leaves cursor in the wrong pl


From: martin rudalics
Subject: Re: undo after repeatedly calling 'repeat' leaves cursor in the wrong place
Date: Sun, 16 Sep 2007 15:12:25 +0200
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

> Type
>   "x C-x z z z z C-x u"
> (to insert an 'x', repeat the insert 4 times, then undo the last of the 4)
>
> Before the "C-x u" there were 5 'x's with the cursor after them all.
> After the "C-x u" there are 4 'x's, as expected, but the cursor is on
> the 2nd one, whereas I would expect it to be after the 4th one.
>
> If "C-x z" is used in full each time, instead of just hitting 'z' over
> and over, then the undo works as expected.

`repeat' has the loop

        (while (eq (read-event) repeat-repeat-char)
          ;; Make each repetition undo separately.
          (undo-boundary)
          (repeat repeat-arg))

Note that `read-event' does not update `last_point_position' and
`undo-boundary' inserts nil into `buffer-undo-list' which prevents
combining the insertions.  `record_insert' calls `record_point' with the
positions where an "x" shall be inserted (2, 3, ...) but `record_point'
still relies on the old position (namely 2) stored for
`last_point_position', decides that it is not equal to point in

      if (last_point_position != pt)
        current_buffer->undo_list
          = Fcons (make_number (last_point_position), 
current_buffer->undo_list);

and repeatedly inserts a 2 into `buffer-undo-list'.  Note that
replacing the latter by

      if (last_point_position != pt)
        {
          current_buffer->undo_list
            = Fcons (make_number (last_point_position), 
current_buffer->undo_list);
          last_point_position = pt;
        }

still gets an off-by-one error.  I think two changes are needed:

(1) For a self-insert-command `repeat' should not construct undo
boundaries.  This would correct the bug reported by Chris but fail for
more complex commands.

(2) Use a separate variable, locally bound in `repeat' around the
recursive call to itself, to assert that `record_point' updates
`last_point_position' before comparing it with `pt'.  Maybe someone has
an idea how to avoid such a variable.  I'd rather not remove such items
from `buffer-undo-list' manually.





reply via email to

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