File: track-changes.el.html

This library is a layer of abstraction above before-change-functions and after-change-functions which takes care of accumulating changes until a time when its client finds it convenient to react to them.

It provides an API that is easier to use correctly than our
*-change-functions hooks. Problems that it claims to solve:

- Before and after calls are not necessarily paired.
- The beg/end values don't always match.
- There's usually only one call to the hooks per command but
  there can be thousands of calls from within a single command,
  so naive users will tend to write code that performs poorly
  in those rare cases.
- The hooks are run at a fairly low-level so there are things they
  really shouldn't do, such as modify the buffer or wait.
- The after call doesn't get enough info to rebuild the before-change state,
  so some callers need to use both before-c-f and after-c-f (and then
  deal with the first two points above).

The new API is almost like after-change-functions except that:
- It provides the "before string" (i.e. the previous content of
  the changed area) rather than only its length.
- It can combine several changes into larger ones.
- Clients do not have to process changes right away, instead they
  can let changes accumulate (by combining them into a larger change)
  until it is convenient for them to process them.
- By default, changes are signaled at most once per command.

The API consists in the following functions:

    (track-changes-register SIGNAL &key NOBEFORE DISJOINT IMMEDIATE)
    (track-changes-fetch ID FUNC)
    (track-changes-unregister ID)

A typical use case might look like:

    (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 (id) (track-changes-fetch id (lambda (beg end before) ..DO THE THING..))))))))

Defined variables (13)

track-changes--before-begBeginning position of the remembered "before string".
track-changes--before-cleanStatus of ‘track-changes--before-*’ vars.
track-changes--before-endEnd position of the text replacing the "before string".
track-changes--before-noIf non-nil, all the trackers are ‘nobefore’.
track-changes--before-stringString holding some contents of the buffer before the current change.
track-changes--buffer-sizeCurrent size of the buffer, as far as this library knows.
track-changes--clean-trackersList of trackers that are clean.
track-changes--disjoint-trackersList of trackers that want to react to disjoint changes.
track-changes--error-logList of errors encountered.
track-changes--traceRing holding a trace of recent calls to the API.
track-changes--trackersList of trackers currently registered in the buffer.
track-changes-record-errorsIf non-nil, keep track of errors in ‘before/after-change-functions’ calls.
track-changes-undo-onlyBound to non-nil by ‘track-changes-fetch’ if the change was an undo.

Defined functions (41)

copy-track-changes--state(ARG)
copy-track-changes--tracker(ARG)
track-changes--after(BEG END LEN)
track-changes--backtrace(N &optional BASE)
track-changes--before(BEG END)
track-changes--call-signal(BUF TRACKER)
track-changes--in-revert(BEG END BEFORE FUNC)
track-changes--pending-p(ID)
track-changes--recover-from-error(&optional INFO)
track-changes--reset(ID)
track-changes--state()
track-changes--state--cmacro(CL-WHOLE-ARG)
track-changes--state-before(track-changes--state-before X)
track-changes--state-before--inliner(INLINE--FORM X)
track-changes--state-beg(track-changes--state-beg X)
track-changes--state-beg--inliner(INLINE--FORM X)
track-changes--state-end(track-changes--state-end X)
track-changes--state-end--inliner(INLINE--FORM X)
track-changes--state-next(track-changes--state-next X)
track-changes--state-next--inliner(INLINE--FORM X)
track-changes--state-p(X)
track-changes--state-p--inliner(INLINE--FORM X)
track-changes--state-undo(track-changes--state-undo X)
track-changes--state-undo--inliner(INLINE--FORM X)
track-changes--tracker(SIGNAL STATE &optional NOBEFORE IMMEDIATE)
track-changes--tracker--cmacro(CL-WHOLE-ARG SIGNAL STATE &optional NOBEFORE IMMEDIATE)
track-changes--tracker-immediate(track-changes--tracker-immediate X)
track-changes--tracker-immediate--inliner(INLINE--FORM X)
track-changes--tracker-nobefore(track-changes--tracker-nobefore X)
track-changes--tracker-nobefore--inliner(INLINE--FORM X)
track-changes--tracker-p(X)
track-changes--tracker-p--inliner(INLINE--FORM X)
track-changes--tracker-signal(track-changes--tracker-signal X)
track-changes--tracker-signal--inliner(INLINE--FORM X)
track-changes--tracker-state(track-changes--tracker-state X)
track-changes--tracker-state--inliner(INLINE--FORM X)
track-changes-fetch(ID FUNC)
track-changes-inconsistent-state-p()
track-changes-register
track-changes-unregister(ID)
with--track-changes(ID VARS &rest BODY)

Defined faces (0)