Question

I've just started playing with emacs modes. I've made a derived-mode (from text-mode), which does simple color modifications for different situations. For example, text above a line of all equal signs (=) is turned magenta, this is done using the code:

(make-face 'heading-face1)
(set-face-foreground 'heading-face1 "brightmagenta")
(set-face-attribute 'heading-face1 nil :weight 'ultra-bold)                                                                                                                                                           
(setq font-lock-heading-face1 'heading-face1)

(font-lock-add-keywords nil '(("\\(.*\n=\\{5,\\}.*\\)"
                           1 font-lock-heading-face1 prepend)))

When I first open a file that has such text, it is colored appropriately; but if I add an extra =, or create a new line of =============, they turn to the normal text color.

Other font-locks do work dynamically. For example, numbers immediately use a different color...

What would cause patterns to be matched differently dynamically from when the file is first opened?

Was it helpful?

Solution

The problem you're facing is that font-lock needs special care when handling multiline keywords.

When you first open your file, font-lock does the highlighting in rather big blocks (~500bytes IIRC), but after the buffer has been changed in some way font-lock will by default only rehighlight it line-by-line for optimization reasons, which means that when it'll consider your heading lines its working region won't even include the next line to perform a match.

A quick fix would be to add a hook to font-lock-extend-region-functions that would extend your rehighlighting region if your special ={5,}.* line is either the first line of the region or the first line after the region. This is not the only (and probably not the most optimal) way to do it, but it should work.

See Multiline Font Lock Constructs section of EmacsLisp manual for more info.

OTHER TIPS

The order of your font-lock keywords matters, if more than one pattern matches. Try using t instead of prepend.

As to why it works when the file is first opened: Perhaps when you first open the file it first gets font-locked normally and then you add your new rule.

(FWIW: You don't need the variable font-lock-heading-face1, at least not for the code shown -- just use the face symbol. And consider just defining the face with defface.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top