Automatically highlight regular expressions

While reading the nice Straightforward Emacs: Automatically Highlight Buffer Text1, I kept wondering whether I could get a similar solution with Emacs built-in facilities. The article explains how to highlight “TK” and variations of it (e.g., “TKTKTKTK”) using the helpful hl-prog-extra2. The author says they had to rely on an external package “after some searching and trial and error”, but it is in fact possible to avoid hl-prog-extra for the simple problem they are trying to solve. The trick is using font-lock-add-keywords.

First of all, I am going to use a custom face instead of the font-lock-warning-face one used in the original article, because I like to think of “TK” as a comment instead of a warning.

(defface mu-tk-face '((t :inherit font-lock-comment-face :bold t))
  "Face used to highlight \"TK\" markers.")

Then I am going to create a small function to hook into the mode where I want to use “TK” markers.

(defvar mu-tk-regexp "\\(TK\\)+"
  "Regexp to identify \"TK\" markers.")

(defun mu-markdown-mode-setup ()
  "Configure `markdown-mode'."
  (font-lock-add-keywords nil `((,mu-tk-regexp 0 'mu-tk-face))))

The rest is trivial:

(add-hook 'markdown-mode-hook #'mu-markdown-mode-setup)

This should be enough already, but since I use flyspell-mode in my Markdown documents it has to ignore “TK” so as to avoid having the flyspell-incorrect face interfering with my own mu-tk-face. In order to accomplish this, I need a function that ignores these markers so I can use it as the value of flyspell-generic-check-word-predicate.

(defun mu-flyspell-skip-tk ()
  "Ignore \"TK\" markers when spell-checking."
  (not (string-match-p mu-tk-regexp (thing-at-point 'word t))))

Finally it’s enough to add the following to mu-markdown-mode-setup:

(setq-local flyspell-generic-check-word-predicate #'mu-flyspell-skip-tk)

Now I can use “TK” markers as intended.

Hopefully it should be obvious that I am not advising against using hl-prog-extra for your highlighting needs. My code is a small solution to a tiny itch, while the scope of hl-prog-extra is much larger. The intent of this writing is just showing that for certain tasks Emacs comes already prepared.