1

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)
func
proc
height

# 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
high
low
medium

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)

jamesmaj
  • 341
  • 1
  • 8
  • 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. – Lindydancer Aug 28 '20 at 06:48

1 Answers1

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.

Fran Burstall
  • 3,665
  • 10
  • 18