Reputation: 873
I'm writing an emacs major mode for a programming environment which supports two slightly different programming languages. Both are lisps (one is Scheme), so both use s-expressions. The two languages are differentiated by their function definition keyword: scheme uses define
, while the other language (which is called xtlang) uses bind-func
So, in the same buffer, I have
(define foo ; this is scheme
(lambda (a)
(+ scheme-fn a))
(bind-func bar ; this is xtlang
(lambda (b)
(* xtlang-fn b))
I've got the font-locking working, using something like
(font-lock-add-keywords nil
'(("(\\(define\\)\\>"
(1 font-lock-keyword-face))
("(\\(bind-func\\)\\>"
(1 font-lock-keyword-face))
("\\<scheme-fn\\>"
(0 font-lock-function-name-face))
("\\<xtlang-fn\\>"
(0 font-lock-function-name-face))
))
What I'd like to be able to do is to be able to colour the parens differently based on the language (scheme/xtlang).
So, colour all the parens in the form red if the top-level defun is a define
, and blue if it's a bind-func
, while still highlighting all the keywords/functions within the forms as normal.
This may require multi-line font locking, since the define
/bind-func
will probably be on a previous line to the keywords to be highlighted. This thread suggests that font-lock-multiline
in conjunction with match-anchored in font-lock-keywords
may be the answer, but then goes on to suggest that font-lock-multiline
should only be used in situations where the multi-line aspect is the exception rather than the rule.
My other option seems to be to use syntax-propertize
, but I'm a bit confused about how that works - the documentation is a bit sparse.
Upvotes: 2
Views: 286
Reputation: 26144
The easiest way to handle this is utilizing the following fact:
MATCHER can be either the regexp to search for, or the function name to call to make the search (called with one argument, the limit of the search;
In other words, you could replace regexps like "\\<scheme-fn\\>"
with a function that repeatedly search for the regexp using re-search-forward
, and return if a match is found in the correct context.
For a concrete example of a package that use this technique, look at cwarn-mode
, which is part of the standard Emacs distribution.
Upvotes: 1