2018-07-09 A mistake with modes and advice

In my last post I wrote about a way to do something only in modes derived from text-mode. Alas, as user Omar pointed out in the comment, I made a rather embarrassing mistake of saying

(add-hook
 'text-mode-hook
 (lambda ()
   (advice-add 'insert-for-yank :before #'set-point-before-yanking)))

Of course, this won’t advise my function in text-mode only, but will install the advice globally (since there’s no other way to do that!) whenever we enter that mode (or any derived mode) for the first time.

The solution can be seen in the corrected version, but it amounts to saying something along the lines of

(defun set-point-before-yanking-if-in-text-mode (string)
  "Invoke `set-point-before-yanking' in text modes."
  (when (derived-mode-p 'text-mode)
    (set-point-before-yanking string)))

(advice-add
 'insert-for-yank
 :before
 #'set-point-before-yanking-if-in-text-mode)

which installs the advice globally, but makes it first check whether we are indeed in a mode which is derived from text-mode and perform its magic only if we are. Note the derived-mode-p function, which handily does that check for us (I learned about it from this answer on StackOverflow).

Interestingly, had we used hooks instead of advice, there would be another method of doing a similar check: add-hook has an optional fourth argument local which modifies the hook only in the current buffer. Alas, I do not know about any Emacs hook which would help here.

CategoryEnglish, CategoryBlog, CategoryEmacs