[Top][All Lists]
[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.