3

I would like to make a mode that would react to user changing the buffer. One way i know is to use hooks.

What hooks, other then post-self-insert-hook, should i use?

What changes i am interested in:

  • entering text
  • changing indentation
  • deleting text
  • yanking

And maybe, in future, so-to-sy:

  • changes in cursor position

In general, some way to react to changes in the buffer would be sufficient.

  • 1
    The emacswiki has a few ideas you can look at: emacswiki.org/emacs/TrackChanges – lawlist Jul 4 '16 at 6:55
  • 1
    Tracking cursor position changes is a completely different ball game (since every window showing a given buffer has its own point): better make a separate question for that. – Stefan Jul 4 '16 at 22:35
7

To react to buffer changes, you generally want to use after-change-functions (or sometimes before-change-functions).

These hooks are run everytime some part of the buffer is modified, either by inserting or by deleting a chunk of text (or text-properties). Be aware that some commands work by applying several modifications to the buffer, so those hooks can be run several (or even many) times in a single command. So if you need to perform a a significant amount of work, it is often useful to use 2-step approach, where an after-change-function only keeps track of the affected region, and then a post-command-hook uses that data to perform the heavy lifting.

E.g.

(defvar foo-unhandled-changes nil)
(defun foo-after-change-function (beg end _len)
  "Remember to fixup the text between BEG and END."
  (unless undo-in-progress
    (if foo-unhandled-changes
        (setq foo-unhandled-changes
              (cons (min beg (car foo-unhandled-changes))
                    (max end (cdr foo-unhandled-changes))))
      (setq foo-unhandled-changes (cons beg end)))))

then use (add-hook 'after-change-functions #'foo-after-change-function nil t) where needed, plus a post-command-hook which can use foo-unhandled-changes to know which part of the buffer (if any) was modified since last time it was run (and which should reset foo-unhandled-changes to nil).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.