Subject: bug#23906: 25.0.95; Undo boundary after process output is not consistent

From: [email-masked] (Phillip Lord)
Date: Tue, 12 Jul 2016 17:29:50 +0100

Markus Triska <[email-masked]> writes:

> [email-masked] (Phillip Lord) writes:
>
>> I assume that the %@ is inserted first before the process is started,
>> then the results put in after the results come back?
>
> The precise sequence is (see `ediprolog-query' and `ediprolog-interact'):
>
> 1) "\n%@ " is inserted into the buffer
> 2) the Prolog process is started (if necessary)
> 3) the query is sent to the process
> 4) when process output arrives, it is appended to the buffer.
>
> The buffer is modified only by (1) and (4). Somtimes there is an undo
> boundary between them, and most often there is none (which I prefer).

Yes. So the issue here is that between 1) and 4) there is a
indeterminate length of time. In Emacs-24, for example, if you run any
command which modify a buffer between 1) and 4) then, also, you would
get an undo after %@.

>> This would mean that after the insertion of %@ there would be no
>> undo-boundary.
>
> That's exactly what I expect to happen. But in some cases, there
> unexpectedly *is* an undo boundary between two subsequent insertions of
> text into the buffer, namely between (1) and (4) above.

The problem here also is what happens if the process output is long.
Emacs will now add undo-boundaries periodically. Before, I think, the
undo list would have got longer and longer, until emacs errored.

>> You could check by adding %@ immediately before you insert data from
>> prolog, rather than after you send data to it. To me, this makes more
>> sense -- you are adding text over an elongated period (i.e. during the
>> evaluation) without the expectation of an undo boundary.
>
> I will try this, thank you for the suggestion! For completeness: I now
> insert %@ *before* I send data to Prolog: (1), then (3) above. I suppose
> you means that I should do (1) immediately before (4), which in fact
> means that I then *would* insert %@ *after* sending data to Prolog.

Yes. Or rather you could insert %@ immediately before getting data back
from prolog, perhaps with a process filter. Then both of your insertions
would be happening together.

If you want the %@ to still *appear* in the buffer after 2), then you
could use a text property to display something, without actually
changing the buffer, perhaps.

>> Likewise, forcing an undo-boundary immediately after %@ would give you
>> consistent behaviour (although different).
>
> Yes, that would be consistent but rather the opposite of what I want: I
> would like to avoid the undo-boundary in all cases.
>
>> In this case, though, I am inclined toward suggesting changing
>> ediprolog.el.
>
> I am willing to do that if it achieves consistent results. However, a
> bit of reflection is in order because other packages may benefit at the
> same time by a more general solution. Please let me know if the use case
> is now clear: To repeat, the issue I am reporting is that sometimes
> there unexpectedly is an undo boundary although I do not want one. From
> the above, it seems that you agree that there should never be an undo
> boundary if the insertion of %@ is directly (except for timing) followed
> by the insertion of arriving process output. Yet, the timing seems to be
> critically involved. So, what would be a general way to always prevent an
> undo boundary between insertions that are separated only by time?
>
> I really like your suggestion to temporarily suppress the timer on a
> specific buffer, say via a let-binding, while the interaction is in
> progress. This would allow users to always undo the *whole* interaction
> with Prolog using a single undo. This is what is typically needed when
> using ediprolog: You interact with Prolog, and then undo the whole
> interaction. In this use case, undo boundaries only get in the way. I
> can make this configurable in ediprolog to perserve memory, if needed.

I could add that, but the problem is that the timer is meant to prevent
the buffer-undo-list from over-running.

In this case, I'm still inclined toward thinking that the changed
semantics of undo are really uncovering an issue with ediprolog -- you
are expecting two events which are temporally separated to be a single
undo; with Emacs-24.5 it's possible to split them also just in a
different way -- for example if another process was generating output.
Also, what happens if point moves between 1) and 4)?

We could also add specific support for removing the last undo, which you
could do iff point is immediately after $@.

Stefan, any thoughts?

Phil