0

I'm trying to write a small new mode for some input files to a specific computational physics program. I'm doing it the define-derived-mode way, and was specifying the syntax highlighting by setting the font-lock-defaults variable, when I realized I needed a regex that does "match any lone words between a line start and an equals sign, not including the equals sign."

This is relatively straightforward with extended regex; I found a quite popular SO answer that gave a short solution in terms of a zero-width assertion. However, I don't see any extended regex support in the manual.

Is there a way to do this with Emacs' regex? If not, is there a way to do it with rx (with which I'm an absolue novice)? Failing that, how do packages like cc-mode which need to do something similar to identify different parts of e.g. a variable declaration in their syntax highlighting do this?

1
  • rx is excellent, but its purpose is to compile structured forms into regexp strings -- there isn't a separate regexp engine involved. Everything you can express in rx can, by definition, also be expressed in the normal string regexp syntax.
    – phils
    Nov 23, 2021 at 21:07

2 Answers 2

1

If a regexp doesn't work, you can use function that does the matching for you. If it behave as a match function, i.e. set match-data and return non-nil when it match something, you can continue to use the font-lock keyword to specify which face to apply to which part of the match.

See the documentation for font-lock-keywords for more details.

One such package that use this technique is https://github.com/Lindydancer/cmake-font-lock -- for example cmake-font-lock-match-dollar-braces is used to match the ${xxx} construct.

2

If you want to match foo= and then highlight the foo part, font-lock allows you to do that by grouping sub-expressions in the regexp and then highlighting only a specified sub-expression. Look for SUBEXP in C-h v font-lock-keywords.

C-hig (elisp)Search-based Fontification says:

‘(MATCHER . SUBEXP)’
     In this kind of element, MATCHER is either a regular expression or
     a function, as described above.  The CDR, SUBEXP, specifies which
     subexpression of MATCHER should be highlighted (instead of the
     entire text that MATCHER matched).

          ;; Highlight the ‘bar’ in each occurrence of ‘fubar’,
          ;; using ‘font-lock-keyword-face’.
          ("fu\\(bar\\)" . 1)

     If you use ‘regexp-opt’ to produce the regular expression MATCHER,
     you can use ‘regexp-opt-depth’ (*note Regexp Functions::) to
     calculate the value for SUBEXP.

Your Answer

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

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