I think you'd need to use polling, sadly.
Detecting via polling that a change happened isn't very hard. Detecting which change happened would in general require keeping a copy of the buffer's contents, but if you're willing to assume that the buffer is only modified by adding to its end or removing from its beginning, you can make it much cheaper.
(run-with-timer 1 t #'sm-poll-message-changes)
(add-hook 'post-command-hook #'sm-poll-message-changes)
(defvar sm--pmc-marker nil)
(defvar sm--pmc-marker-pos nil)
(defvar sm--pmc-tick nil)
(with-current-buffer (get-buffer "*Messages*")
(setq sm--pmc-marker (point-max-marker)))
(setq sm--pmc-marker-pos (point-max))
(setq sm--pmc-tick (buffer-chars-modified-tick)))
(defun sm-poll-message-changes ()
(with-current-buffer (marker-buffer sm--pmc-marker)
(unless (eq sm--pmc-tick (buffer-chars-modified-tick))
;; A change happened.
(let ((deleted-chars-at-bob
(- sm--pmc-marker-pos sm--pmc-marker))
(inserted-chars-at-eob
(- (point-max) sm--pmc-marker)))
(setq sm--pmc-marker-pos (point-max))
(setq sm--pmc-tick (buffer-chars-modified-tick))
(move-marker sm--pmc-marker (point-max))
...DO-YOUR-THING-HERE...)))))
message
, but it's not clear whether that's sufficient, or sensible. If you're trying to debug something, use thedebug-on-message
variable (available since 24.3).message
. I want to be able to fire a function whenever the contents of*Messages*
change. I appreciate your efforts in trying to solve my root problem and will consider whether there is a better way to contextualize the problem. I believe this question in its current state is unambiguously answerable according to SX guidelines, and I want to be careful about adding more information.message
wouldn't work for messages emitted by primitives. It would be risky for what is probably the reason that no hook fires when a message is emitted: any error or other message emitted from that advice/hook would cause recursion, so you'd need to be careful and disable the hook (likepost-command-hook
) in case this happens.*Messages*
buffer, but the code that inserts the messages into it.