From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: An idea: combine-change-calls Date: Thu, 29 Mar 2018 15:10:47 -0400 Message-ID: References: <20180326201728.GA28620@ACM> <20180327165816.GB4105@ACM> <20180327194507.GD4105@ACM> <20180328204254.GC6592@ACM> <20180329151033.GA5213@ACM> <20180329171101.GB5213@ACM> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1522350537 10154 195.159.176.226 (29 Mar 2018 19:08:57 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 29 Mar 2018 19:08:57 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Alan Mackenzie Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Mar 29 21:08:53 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1f1cuq-0002YN-Jl for ged-emacs-devel@m.gmane.org; Thu, 29 Mar 2018 21:08:52 +0200 Original-Received: from localhost ([::1]:50140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f1cwu-0005eX-6E for ged-emacs-devel@m.gmane.org; Thu, 29 Mar 2018 15:11:00 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54837) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f1cwn-0005dv-29 for emacs-devel@gnu.org; Thu, 29 Mar 2018 15:10:54 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f1cwj-0005mr-Rv for emacs-devel@gnu.org; Thu, 29 Mar 2018 15:10:53 -0400 Original-Received: from pruche.dit.umontreal.ca ([132.204.246.22]:34381) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f1cwj-0005ke-Le for emacs-devel@gnu.org; Thu, 29 Mar 2018 15:10:49 -0400 Original-Received: from pastel.home (lechon.iro.umontreal.ca [132.204.27.242]) by pruche.dit.umontreal.ca (8.14.7/8.14.1) with ESMTP id w2TJAlKu023037; Thu, 29 Mar 2018 15:10:47 -0400 Original-Received: by pastel.home (Postfix, from userid 20848) id 7A41860559; Thu, 29 Mar 2018 15:10:47 -0400 (EDT) In-Reply-To: <20180329171101.GB5213@ACM> (Alan Mackenzie's message of "Thu, 29 Mar 2018 17:11:01 +0000") X-NAI-Spam-Flag: NO X-NAI-Spam-Threshold: 5 X-NAI-Spam-Score: 0 X-NAI-Spam-Rules: 2 Rules triggered EDT_SA_DN_PASS=0, RV6253=0 X-NAI-Spam-Version: 2.3.0.9418 : core <6253> : inlines <6528> : streams <1782627> : uri <2616983> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 132.204.246.22 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:224162 Archived-At: > Right, I think I've got it now. The macro combine-change-calls would > maybe first push some sort of sentinal element onto buffer-undo-list, > then let ,@forms run, then massage the list so that the 2000 elements > created by ,@forms would become part of the `apply' element. Right. Now you can re-read the pseudo-code I had sent: (let ((elem-apply `(apply 0 ,beg ,end ,#'my-undo-combining nil))) (push elem-apply buffer-undo-list) (funcall body) (let ((new-bul (memq elem-apply buffer-undo-list))) (when new-bul (let ((undo-elems buffer-undo-list)) (setf (nthcdr (- (length undo-elems) (length new-bul)) undo-elems) nil) (setf (nth 1 elem-apply) (- end-marker end)) (setf (nth 3 elem-apply) (marker-position end-marker)) (setf (nth 5 elem-apply) undo-elems) (setq buffer-undo-list new-bul))))) and then (defun my-undo-combining (undo-elems) (let ((inhibit-modification-hooks t)) (while t (primitive-undo 1 undo-elems)))) >> That it can be used by other things than combine-change-calls. >> I.e. generic is the same sense as the (apply ....) thingy is generic. > I still don't understand. What other things could possibly be similiar > enough to collecting before/after-change-functions to be abstractable > into some sort of parameter? Could you give an example? I could imagine a macro `with-inhibit-read-only` which would bind inhibit-read-only to t and then tweak the buffer-undo-list similarly to what you're doing such that the undo is also performed with inhibit-read-only bound to t. >> Could you give some hypothetical example to give me an idea of what kind >> of info you're thinking of and where/when it might be needed? > The information is the original undo entries created by the Emacs > primitives whilst in combine-change-calls. > As to where/when/why it might be needed, I couldn't say at this point. > Somebody, sometime, will want it for some reason, just like you said in > your piece about "hiding information" I quoted a short while ago. > Why are you so keen to destroy this detailed information? I'm not interested in destroying this information. I'm just trying to solve the problem at hand and it's a simple and efficient solution, and neither you nor I can come up with a scenario where this simpler solution is worse, apparently. > Its continued existence does not cause any disadvantage. The run time > which would be saved in `undo' is minimal and inconsequential. Agreed, the gain is in the simplicity of combine-change-calls. >> I'm referring to undo-boundaries pushed by the "execution of >> `body`", not by your code. > OK. We could amend primitive-undo such that the argument N could, > additionally, take the value t, meaning "undo all elements in the list, > ignoring nils". Or something like that. We don't need that: can call it repeatedly until it returns nil. >> IIUC we agree that this is considered an unimportant use-case and it's >> OK to just ignore such boundaries. > I suppose so. What would such a boundary mean anyway? We're talking > about a scenario where all the change hook invocations are amalgamated. > How could it make sense to split that up? Some commands explicitly push undo boundaries in the middle of their execution, so that the user can easily undo the 2nd half of the command's execution, for example. This is rare enough that I think it's perfectly OK to say that such use-cases are not supported by combine-change-calls. [ It's also the only use-case I could think of where using a simple pair of "delete+insert" undo entries would have made a difference. ] Stefan