While reading the nice Straightforward Emacs: Automatically Highlight Buffer
Text, 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-extra. 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.