Subject: Re: bug#22295: viper-mode undo bug introduced between Nov 10 and Nov 14

From: Michael Kifer <[email-masked]>
Date: Mon, 16 May 2016 13:14:05 -0400

On 05/16/2016 12:34 PM, Eli Zaretskii wrote:

From: Jim Meyering <[email-masked]>
Date: Mon, 16 May 2016 08:39:15 -0700
Cc: Eli Zaretskii <[email-masked]>, Michael Kifer <[email-masked]>, [email-masked]

Thank you.
That does indeed fix the case I mentioned.
Here are some cases where it does not work as expected:

start with an empty buffer in viper-mode
type 'i 1 2 3 4 5ESC'
type 'F2dw' to delete the 2 and a space.
type 'wdw' to delete the 4 and a space.

Now, if I were to hit "u" to undo, I would expect that most recent
deletion to be undone and the 4 would reappear.
Then I would hit '.' to undo the deletion of the '2'. Finally one more
'.' would undo the creation of that first line.
However, with the current patches, that first 'u' undoes everything
and leaves me with the empty initial file.

Another example starting with an empty file:
Create some content via ':r!seq 999|fmt RETURN'
Then remove e.g., "222 " and "444 " via '/222' RET 'dw',
then '/444' RET 'dw'. Now, we expect a single 'u' to restore the '444 ',
yet it undoes everything, leaving an empty buffer.
Hmm... that's probably no different from the first example.

One more, then. Starting with this input:

1 2 3 4 5 6

advance to the '2' with 'w', 'dw' to delete the 2, then three '.'s to
delete the 3, then 4 and 5.
Then begin to undo with 'u', then '.' to repeat it. Those first two
work, restoring the 5 and 4.
However, one more '.' restores both the 3 and the 2.

Thanks. It now looks like your expectations are close to what Emacs
does by default, whereas Michael said the VI undo is more coarse (and
in the original recipe, it indeed seemed to be that).

Is it possible to have a more general/formal description of what
'undo' in VI is supposed to do? E.g., it looks like it has different
granularities wrt insertions and deletions, is that correct?

You see, when I said this is undocumented, I meant precisely that: the
expected effect of 'undo' in VI is not described, so someone who is
not a VI user doesn't know what to test and how to program that.

In VI, an undo is supposed to undo the effect of the previous VI command.  In Emacs terms, each such command usually means several inserts and deletes, which in Emacs would be undone via a series of undos. Such behavior is a non-no to a vi user.

Michael said that this _is_ documented, but the only documentation I
see is comments that describe _what_ they do in terms of Emacs undo
structures, and are full of "rationale" such as "so that things will
be undone properly". I don't see any description of the expected
effect of undoing in different situations, let alone some formal
specification of undo-related requirements. If I missed some
description of how undo is supposed to work in viper, please just
point me there.

I was referring to the insertion of a special marker into the undo list. Obviously, the usual Vi conventions are not documented because this would require to duplicate the Vi manual.

Another alternative is to make viper use the default Emacs undo, and
then ask you and other users of viper to tell where the results don't
match your expectations. It could well be that starting with a clean
slate will get us to the goal faster and with less complex code.

This would be a non-starter and would cause a mass migration to vim. The undo would also then be implementation dependent.  If, say, "delete 2 words" is implemented differently from how it is now then it would  be undone via a different sequence of commands.

--

--- michael