I'm writing a syntax highlighting mode and am trying to highlight certain arguments, only if they are following a specific word.

I've written a MWE to show my problem:

(defvar mwe-builtin-list '("func" "proc" "height"))
(defvar mwe-args-list '("high" "low" "meduim"))

(setq mwe-builtin-regexp (regexp-opt mwe-builtin-list 'symbols))
(setq mwe-args-regexp (concat "height " (regexp-opt mwe-args-list)))

(defvar mwe-font-lock-keywords
    (,mwe-builtin-regexp (0 font-lock-builtin-face))
    (,mwe-args-regexp (2 font-lock-keyword-face)) ;; <- Not working

(define-derived-mode mwe-mode prog-mode "MWE-mode"
  "Major mode for MWE mode to tinker with syntax highlighting"
  (font-lock-add-keywords nil mwe-font-lock-keywords))

(provide 'mwe-mode)

For the example buffer which contains:

# words should have font-lock-builtin-face (working)

# word "height" should have font-lock-builtin-face (working)
# word high|low should have font-lock-keyword-face (not working)
height high
height low

# should not be highlighted as out of context

All the "func|proc|height" words are highlighted correctly, but the high|low arguments in the second paragraph aren't highlighted.

I don't want to simplify the mwe-args-regexp to match all instances of "high|low|medium" as I want the third paragraph to not be highlighted (the arguments are there, but not in the correct context to be highlighted)

  • 1
    One way to solve this is to use an "anchored" font-lock keyword. This is like a search-within-a-search, where func etc. would be main regexp and high etc. the secondary. By default, the secondary is matched from the point to the end of the line, but it's possible to adjust the scope. Another is to search for high using code and add an extra check that it is in the correct scope. Commented Aug 28, 2020 at 6:48

1 Answer 1


In mwe-args-regexp you need (regexp-opt mwe-args-list "\\(?2:") and then everything should work.

Explanation: without the extra argument, regexp-opt produces a shy group construct which cannot be given a sub-match number.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.