Subject: bug#70077: An easier way to track buffer changes

From: Stefan Monnier <[email-masked]>
Date: Fri, 29 Mar 2024 14:53:41 -0400

> I cannot imagine how applications would use these APIs.  I'm probably
> missing something, org the above documentation does.  Can you show
> some real-life examples?

Haven't written real code for it yes, no.
The best I can offer is the sample code in the file:

    (defvar my-foo--change-tracker nil)
    (define-minor-mode my-foo-mode
      "Fooing like there's no tomorrow."
      (if (null my-foo-mode)
          (when my-foo--change-tracker
            (track-changes-unregister my-foo--change-tracker)
            (setq my-foo--change-tracker nil))
        (unless my-foo--change-tracker
          (setq my-foo--change-tracker
                (track-changes-register
                 (lambda ()
                   (track-changes-fetch
                    my-foo--change-tracker
                    (lambda (beg end before)
                      ..DO THE THING..))))))))

Where "DO THE THING" is run similarly to what would happen in an
`after-change-functions`, except:

- BEFORE is a string holding the content of what was in BEG..END
  instead of being limited to its length.
- It's run at most once per command, so there's no performance worries.
- It's run "outside" of the modifications themselves,
  so `inhibit-modification-hooks` is nil and the code can wait, modify
  the buffer, or do any kind of crazy things.

The code can also be changed to:

                [...]
                (track-changes-register
                 (lambda ()
                   (run-with-idle-timer
                    2 nil
                    (lambda ()
                      (track-changes-fetch
                       my-foo--change-tracker
                       (lambda (beg end before)
                         ..DO THE THING..))))))))

without any extra work.

        Stefan