From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Markus Triska Newsgroups: gmane.emacs.bugs Subject: bug#23906: 25.0.95; Undo boundary after process output is not consistent Date: Tue, 12 Jul 2016 20:56:21 +0200 Message-ID: <874m7usn1m.fsf@metalevel.at> References: <83r3b6lih2.fsf@gnu.org> <87h9bw5rfd.fsf@russet.org.uk> <87eg70i8k5.fsf@metalevel.at> <87d1mikef5.fsf@russet.org.uk> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1468349848 3016 80.91.229.3 (12 Jul 2016 18:57:28 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 12 Jul 2016 18:57:28 +0000 (UTC) Cc: Stefan Monnier , 23906@debbugs.gnu.org To: phillip.lord@russet.org.uk (Phillip Lord) Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Jul 12 20:57:15 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1bN2rq-0000wD-VY for geb-bug-gnu-emacs@m.gmane.org; Tue, 12 Jul 2016 20:57:15 +0200 Original-Received: from localhost ([::1]:42745 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2rq-0001Jr-73 for geb-bug-gnu-emacs@m.gmane.org; Tue, 12 Jul 2016 14:57:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55057) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2ri-0001Ji-SQ for bug-gnu-emacs@gnu.org; Tue, 12 Jul 2016 14:57:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bN2re-0001ck-FK for bug-gnu-emacs@gnu.org; Tue, 12 Jul 2016 14:57:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:36346) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2re-0001cg-CV for bug-gnu-emacs@gnu.org; Tue, 12 Jul 2016 14:57:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1bN2re-0005GS-7i for bug-gnu-emacs@gnu.org; Tue, 12 Jul 2016 14:57:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Markus Triska Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 12 Jul 2016 18:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 23906 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 23906-submit@debbugs.gnu.org id=B23906.146834978520180 (code B ref 23906); Tue, 12 Jul 2016 18:57:02 +0000 Original-Received: (at 23906) by debbugs.gnu.org; 12 Jul 2016 18:56:25 +0000 Original-Received: from localhost ([127.0.0.1]:48683 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bN2r3-0005FP-2M for submit@debbugs.gnu.org; Tue, 12 Jul 2016 14:56:25 -0400 Original-Received: from metalevel.at ([78.46.218.83]:35168) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bN2r1-0005FF-A1 for 23906@debbugs.gnu.org; Tue, 12 Jul 2016 14:56:23 -0400 Original-Received: by metalevel.at (Postfix, from userid 1000) id 0CDB6A0640; Tue, 12 Jul 2016 20:56:22 +0200 (CEST) In-Reply-To: <87d1mikef5.fsf@russet.org.uk> (Phillip Lord's message of "Tue, 12 Jul 2016 17:29:50 +0100") User-Agent: Emacs/24.4 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:120943 Archived-At: Hi Phillip, Stefan, I post a bit of information about how ediprolog.el currently works so that the use case is clear. I am perfectly willing to make any adjustments to ediprolog so that undo is treated more consistently. At the same time, I am also interested in improving Emacs generally, so please read this as clarification of, not excuse for, the current state. phillip.lord@russet.org.uk (Phillip Lord) writes: >> 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. 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 ;-) >> 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. > 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. > 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. However, it is indeed possible to escape this loop with C-g and indeed move point and even insert text into the buffer while the process still runs and may produce output that is also inserted into the buffer by the process filter. > Stefan, any thoughts? As to the options outlined by Stefan: 1- just let the user hit undo an extra time when that happens. That is the current state that I consider a bit unsatisfying, so I would like to choose between 2, 3 and 4: 2- Refine the timer-based undo-boundaries along the lines of what you had earlier: only add a timer-based boundary if the last undo chunk is too long (same for undo-boundaries added in non-current buffers). It would still occasionally add "unwanted" boundaries, but only when not doing so would result in too large an undo list. I think we can rule this out as a satisfying solution. 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. 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? 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. Ideally, only the output that stems from the interaction with the Prolog process and user input during the interaction should be treated as a single unit. This separation (i.e., treat insertions as a unit in some parts of a buffer while applying the normal undo behaviour in other parts) may of course be very hard to achieve, and I would already be very satisfied if there is a way to make it work in the regular case. I only mention for completeness that conceptually, I regard the text that stems from the Prolog interaction different from editing operations. Please try ediprolog if possible (any SWI version will do) and try for example the query (M-x ediprolog-dwim RET with point on the line): ?- length(Ls, L). You then interact with SWI-Prolog just as on a terminal. C-g will put you out of the loop and let you edit other text in the buffer. M-x ediprolog-toplevel RET puts you back to the toplevel. You can stop the query at any time by pressing "." or "a". Ideally, pressing C-/ after stopping the query undoes the whole interaction. I hope that this clearifies the use case a bit. Thank you for looking into this! All the best, Markus