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

From: [email-masked] (Phillip Lord)
Date: Wed, 13 Jul 2016 09:09:41 +0100

Markus Triska <[email-masked]> writes:
> Yes, this is the core issue. In simulans2.sh which I posted, you can try
> different time spans between 1) and 4) easily by modifying line 15.  For
> example, if I change 1.5 to 10, I always get an undo boundary after the
> initial %@. If I change it to 4 or 5, I still only sometimes get one. My
> estimate is thus that the timer runs about once every 10 seconds ;-)

Yep, every 10 seconds.

>
>
>>> 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.
>
> To clearify, the use case of ediprolog indeed comprises a single flow of
> insertions, either stemming from process output or user input, while the
> Prolog query is in process: Everything the Prolog process outputs is
> inserted. Everything the user inputs is also inserted into the buffer
> (and sent to the process). The result is a complete transcript of the
> Prolog interaction just as it would normally happen on the terminal.
>
> For this particular case, I would be perfectly OK if undo would simply
> undo the whole flow of insertions up to the point where the query was
> started. I do not know much about the undo representation or your plans
> about it, but what I think would work in this particular case is to
> record it as "Emacs, to undo this, you need to remove all text between X
> and Y", and Y simply increases as more text is inserted into the buffer.
> This would keep the length of the undo list constant throughout the
> whole interaction with the subprocess, at least in this concrete
> case. Can I do this in ediprolog myself? If so, then I will do it.

And what happens if the prolog process spams and never stops? Y, gets
longer and longer. Eventually, Emacs signals an error with a "this is
probably a bug" message.

>> 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.
>
> I am already using a process filter: If the process outputs \n, then I
> insert \n%@ into the buffer. Only for the very first %@ that I insert
> directly after the query is started, I am currently doing it outside the
> process filter. It is important to insert %@ immediately to give an
> indication that the query has been sent to the process (which may take a
> long time to produce output). Note that % starts a Prolog line comment,
> so the process output that gets embedded in buffers does not interfere
> with the Prolog program itself. For this reason, text properties would
> not be a good fit for this use case: Users often want to store the query
> results together with the source code, and using %@ allows that.

I think you are doing two things -- one is telling the user that
something has happened and one is storing the result. I think that this
is the problem.

My suggestion is add the %@ into the buffer when the result comes
through. If you want %@ to *appear* before this, then insert an overlay
with a display string.

>> Also, what happens if point moves between 1) and 4)?
>
> In the typical interaction mode, point cannot move between 1) and 4):
> Each key press is sent to the Prolog process, so that you can interact
> with Prolog like in a terminal.

Emacs blocks?

>    3- Have Ediprolog use the same trick used in Viper where we wipe out
>       intermediate boundaries after the fact.
>
> This sounds like a great option. Could you please tell me a bit more?
> The specific use case for me is: I have a process filter that
> continuously (upon process output or user input) inserts text into the
> buffer. I just want *all* this text gone when pressing C-/. If possible,
> I hope that this can be done without the undo list growing too long.

I don't think that this is needed here. Viper has this because it
removes undo-boundaries when it changes modes -- so it needs to add
undo-boundaries which it later takes out.

>    4- Add the kind of "do it manually" option you had added earlier, such
>       that Ediprolog could request that Emacs refrain from auto-adding any
>       undo-boundaries in its buffer.
>
> To me, this sounds at least as great as (3) and maybe could be used by
> both Viper and ediprolog if it were available?

I have no particular problem with adding this (although not for Emacs
25.1 now!). Again, the caveat is, if the process is long or continual
you MUST do something to call undo-boundary periodically, or Emacs will
error.

>
> Please note in this case that, as explained above, the output normally
> is inserted continuously in a loop, but it is possible to break out of
> the loop with C-g and edit text elsewhere in the buffer, and in that
> case I still would like the normal undo behaviour for user
> input.

Yeah, that's straight-forward -- add undo-boundary on non local exit.

My own feeling here is, still, that while ediprolog's current system is
straight-forward, it's probably not correct!

Phil