To react to buffer changes, you generally want to use
after-change-functions (or sometimes
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.
(defvar foo-unhandled-changes nil)
(defun foo-after-change-function (beg end _len)
"Remember to fixup the text between BEG and END."
(cons (min beg (car foo-unhandled-changes))
(max end (cdr foo-unhandled-changes))))
(setq foo-unhandled-changes (cons beg end)))))
(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).