3

I am writing a major mode derived from f90-mode in order to fontify the syntax of a commonly used Fortran preprocessor, fypp (similar to jinja2 for HTML templating). Here's a contrived example of what that looks like, with plain f90-mode highlighting on the left and my fypp-mode on the right.

f90 vs fypp

The #: directive and the ${...}$ evaluator are new syntax atop Fortran, which is why f90-mode does not color them properly. I want my major mode to inherit the fontifications defined in f90-mode.el and add to them. Here's a minimal but representative implementation

;;; fypp-mode.el

(setq fypp-highlights
      '(("#:set" . font-lock-preprocessor-face)
        ("\\${\\|}\\$" . font-lock-preprocessor-face)))

(define-derived-mode fypp-mode f90-mode "fypp"
  "Major mode for editing Fortran code with fypp extensions"
  (font-lock-add-keywords nil fypp-highlights))

I have two complaints with this, seen in the right-side image above:

  1. The ${...}$ syntax in the subroutine name declaration breaks the fontification of the subroutine name.

  2. The ${...}$ inside a string literal does not get fontified, but I would like it to.

Issue #1 I am able to solve by modifying the syntax table entries for { and } to make them word class instead of parentheses. I do wonder if this is likely to bite me later, though.

Issue #2 is the trickier matter for me. Normally, you want strings fontified as strings, even if they happen to contain keywords. Here, though, the string "Hello, ${whom}$!" will get expanded by the preprocessor to "Hello, world!", so I want the ${...}$ to be fontified. I still want string literals to be fontified, I just want my preprocessing tokens to "take precedence". But I don't know how to do this cleanly, if at all.

Drew
  • 75,699
  • 9
  • 109
  • 225
Endulum
  • 133
  • 3

1 Answers1

2

For issue #1, setting { and } to word syntax is wrong. You can give them "symbol constituent" syntax, but not "word" (otherwise you break the expected behavior of M-f and friends). This said, it may indeed bite you later, depending on what the rest of f90.el does.

For Issue #2, you simply want to use the OVERRIDE field in your font-lock rule. See C-h o font-lock-keywords for details.

Stefan
  • 26,154
  • 3
  • 46
  • 84
  • I see, good call on putting curly braces as symbols rather than words (they are not part of Fortran's syntax, so I expect not to step on any landmines.) Also, thanks for pointing out the OVERRIDE field, that's exactly the kind of thing I was searching for! – Endulum Jul 08 '20 at 06:53