emacs-devel
[Top][All Lists]
Advanced

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

Re: disabling undo boundaries


From: Stefan Monnier
Subject: Re: disabling undo boundaries
Date: Mon, 11 May 2015 15:30:33 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

>> but I can see a few alternatives: - disable undo in the "other buffer"
>> (*scratch* in your example, tho I suspect it's a different buffer in
>> your real case).
> This fails for me, unfortunately, the user might want to undo in the
> other buffer. A priori, though, it seems to be a nice idea. I tried this
> code for instance:
> #+BEGIN_SRC emacs-lisp
>   (defvar-local fix-test-on nil)
>   (defun fix-test-after-change-function (&rest _)
>     (when fix-test-on
>       (let (
>             (undo-inhibit-record-point t)
>             )
>         (with-current-buffer
>             (get-buffer "*scratch*")
>           (insert "a")))))
>   (add-hook 'after-change-functions 'fix-test-after-change-function)
> #+END_SRC
> And that doesn't have the problem because the inhibit stops record_point
> from ever setting the undo_boundary.

So, you're saying that the above let binding fixes your problem?
Then, I guess it's a valid option as well.  It sounds like an obscure
work-around, so it probably deserves a clear comment.

>> - delay the modification of the other buffer (e.g. record in a-c-f the
>> boundaries of the affected text, and process them later from
>> post-command-hook).  Not sure if this would really help.
> Unfortunately that wont work since there there can be many changes on
> a-c-f for a single p-c-h call. So, I'd have to amalgamate all the
> changes.

Amalgamate is exactly what I meant by "record the boundaries".
It's a fairly common approach, typically you only track the beg/end
enclosing boundaries.

E.g. I use it in diff-mode to avoid modifying the buffer right in the
middle of a-c-f, which tends to break all kinds of assumptions.

>> - change your a-c-f so it records the buffer-undo-list at the beginning,
>> and it removes the added boundary (if any) at the end.
> The a-c-f doesn't work, unfortunately because the nil boundary is not
> present till sometime after the a-c-f has been called (when? not sure).

That is weird.  The code you quoted from record_point should be run
"right away".  Are you sure you didn't check in the wrong buffer by
any chance?

I'd expect something like

   (let ((old-ul buffer-undo-list))
     (with-current-buffer "*scratch*"
       <doyourthing>)
     (and (consp buffer-undo-list)
          (eq (cdr buffer-undo-list) old-ul)
          (null (car buffer-undo-list))
          (setq buffer-undo-list (cdr buffer-undo-list))))

to do the trick.  Or, what am I missing?

> I did think of doing this with the pre/post-command-hook -- so, take the
> car of the b-u-l on the pre-c-h, then on the post-c-h, scan till I get
> to the old car and delete all nils placed there.

But at that point you won't know which undo-boundaries were added
because of the buffer-switch and which were added for other reasons.

> I can see a few problems with this. First, it will also remove any
> undo-boundaries added by explict calls to undo-boundary; perhaps not a
> huge problem as there do not appear to be that many of them in the lisp
> code base.

Since `doyourthing' shouldn't touch the source buffer, the source
buffer's undo-list has no reason to have a hand-added undo-boundary.


        Stefan



reply via email to

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