help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: track-changes and undo


From: Stefan Monnier
Subject: Re: track-changes and undo
Date: Mon, 22 Apr 2024 19:04:10 -0400
User-agent: Gnus/5.13 (Gnus v5.13)

>> The gain from `track-changes` is just to provide you with the "before"
>> string for deletions so it takes care of reading it in
>> `before-change-functions` and then providing it to you in the
>> `after-change-functions` (with the advantage that it detects/handles the
>> various corner cases where that pairing fails).
> I think I'll try and see if I can make it work with the `:immediate` option.
> It would of course mean that the buffer is modified inside
> `after-change-functions`, which you warn against,

It wouldn't be worse than what you have now since you also modify the
buffer from `before/after-change-functions`.

> but it looks like that's the only way.

In the general case it's tricky to postpone the buffer change to a safer
time, indeed.  In practice, tho, you should be able to distinguish "undo
commands" from all other commands (basically depending on whether they
do all their modifications with `undo-in-progress` or not) and then
ignore only the changes of undo commands: the result should be
good enough.

IOW something like:

    (track-changes-register #'cm-change-signal :immediate t)

    (defvar-local cm-change-pending nil)

    (defun cm-change-signal (id)
      (cond
       (cm-change-pending nil) ;; Nothing to do, we're already waiting.
       (undo-in-progress
        ;; Just ignore this undo change.
        (track-changes-fetch id #'ignore))
       (t
        (setq cm-change-pending
              (run-with-timer 0 nil #'cm-change-do id)))))
       
    (defun cm-change-do (id)
      (track-changes-fetch
       (lambda (beg end before)
         ..DO THE CriticalMarkup THING..
         ;; Ignore the changes we just made.
         (track-changes-fetch id #'ignore)
         (setq cm-change-pending nil))))

>> One other thing that you might have trouble to reproduce with
>> `track-changes` is the following test:
>>
>>     (and (= beg (point-min)) (= end (point-max)))
>>
>> that you have in `cm-before-change`.  I'm not completely sure what this
>> is for, tho.  Is it for `revert-buffer`?
>
> I honestly don't remember... Based on the comment, it looks like
> `switch-to-buffer` triggers `before-change-functions`, but a) that doesn't 
> make
> much sense; and b) the code seems to work just fine without that line. (I even
> fired up a Vagrant box with an old Ubuntu release with Emacs 24, which would 
> be
> the most recent version when I wrote that code).

Have you tried `M-x revert-buffer RET` (assuming the file and the
buffer aren't equal)?

> Making it a minor mode makes sense, of course.

It was already a minor mode, IMO, just one defined by hand instead of
using the dedicated macro.


        Stefan




reply via email to

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