Pregunta

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.

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top