Im trying to setup font-locking for a major mode. Here is some example code:
USING: foo bar bar ;
IN: fuelcolors
TUPLE: font < super-class
name
size
bold?
italic?
{ foreground initial: COLOR: black }
{ background initial: COLOR: white } ;
TUPLE: rgb red green blue ;
: foobar ( seq -- seq )
hello there { 1 2 3 } ;
The following symbols should be highlighted with some face (doesn't matter which, my problem is the matching part): name, size, bold?, italic?, foreground, background, red, green, blue. They represent names of slots in tuples.
I know a regexp wont do it because the matched region isn't continuous. italic? and foreground should be matched, but not the { character in between those symbols. So instead I thought I could author a font-lock matcher function, similar to the one Dmitri offered here: Context-sensitive font-locking in emacs for a very similar problem.
But afaict, his solution takes advantage of the fact that the "sequence" of items to highlight is inside paranthesises which is not the case here.
Font-lock has trouble with situations like these (Unknown number of matches in regex and font-lock), but I'm still hoping for some "good enough" solution even it if requires hacking font-lock internals.
Here is the solution I ended up with:
(,"\\(TUPLE\\):[ \n]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\(?:[ \n]+<[ \n]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?"
(1 'factor-font-lock-parsing-word)
(2 'factor-font-lock-type-name)
(3 'factor-font-lock-type-name nil t)
("\\(\\(?:\\sw\\|\\s_\\)+\\)\\|\\(?:{[ \n]+\\(\\(?:\\sw\\|\\s_\\)+\\)[^}]+\\)"
((lambda (&rest foo)
(save-excursion
(re-search-forward " ;" nil t)
(1- (point)))))
nil
(1 'factor-font-lock-symbol nil t)
(2 'factor-font-lock-symbol nil t)))