emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: An idea: combine-change-calls


From: Stefan Monnier
Subject: Re: An idea: combine-change-calls
Date: Thu, 29 Mar 2018 15:10:47 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

> 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]