Discussion:
font locking for DEFINE-VALUES in Scheme-like mode
(too old to reply)
Marco Maggi
2014-03-11 06:54:33 UTC
Permalink
Ciao,

for an extended Scheme language I am customising a mode derived from
"scheme-mode"; I think I am on the good road with font locking of the
forms:

(define O 1)
(define {O <byte>} 1)
(define (O a b) 123)
(define ({O <byte>} a b) 123)
(define-method (O a b) 123)
(define-method ({O <byte>} a b) 123)
(case-define ciao
((a) 123))
(case-define {ciao <byte>}
((a) 123))
(define-constant ciao
123)
(define-constant {ciao <byte>}
123)
(define-inline-constant ciao
123)
(define-inline-constant {ciao <byte>}
123)

using, for example, the following components in the custom
*-font-lock-keywords:

;;This does DEFINE and DEFINE-METHOD for function bindings only.
(,(eval-when-compile
(concat "(\\s-*"
(regexp-opt '("define" "define-method") 'symbols)
"\\s-+(" ;any whitespace and open paren
"{?" ;optional open brace
"\\s-*" ;optional white space separator
"\\(" my-scheme-identifier-internal-rex "\\)"))
(1 font-lock-keyword-face)
(2 font-lock-function-name-face nil t))

;;This does DEFINE and DEFINE-CONSTANT for variable bindings only.
(,(eval-when-compile
(concat "(\\s-*"
(regexp-opt '("define" "define-constant"
"define-inline-constant")
'symbols)
"\\s-+" ;any whitespace
"{?" ;optional open brace
"\\s-*" ;optional white space separator
"\\(" my-scheme-identifier-internal-rex "\\)"))
(1 font-lock-keyword-face)
(2 font-lock-variable-name-face nil t))

but I dunno how to go to colorise the following syntaxes:

(define-values (a b c)
(values 1 2 3))
(define-values ({a <byte>} {b <byte>} {c <byte>})
(values 1 2 3))

where:

* DEFINE-VALUES should be "font-lock-keyword-face".

* "a", "b" and "c" should be "font-lock-variable-name-face"; there can
be any number of these identifiers.

* The type tags "<byte>" should be "font-lock-type-face".

To colorise the type tags I have the following font-lock-keywords
component:

(,(eval-when-compile
(concat "\\<\\("
"\\(?:" my-scheme-identifier-internal-rex "\\.\\)?"
"<" my-scheme-identifier-internal-rex ">"
"\\)\\>"))
1 font-lock-type-face)

which does both tags like "<fixnum>" and like "prefix.<fixnum>"; there
should be no need to do anything more.

How do I handle repeated patterns?

TIA
--
"Now feel the funk blast!"
Rage Against the Machine - "Calm like a bomb"
Pascal J. Bourguignon
2014-03-11 14:29:31 UTC
Permalink
Post by Marco Maggi
(define-values (a b c)
(values 1 2 3))
(define-values ({a <byte>} {b <byte>} {c <byte>})
(values 1 2 3))
* DEFINE-VALUES should be "font-lock-keyword-face".
* "a", "b" and "c" should be "font-lock-variable-name-face"; there can
be any number of these identifiers.
* The type tags "<byte>" should be "font-lock-type-face".
To colorise the type tags I have the following font-lock-keywords
(,(eval-when-compile
(concat "\\<\\("
"\\(?:" my-scheme-identifier-internal-rex "\\.\\)?"
"<" my-scheme-identifier-internal-rex ">"
"\\)\\>"))
1 font-lock-type-face)
which does both tags like "<fixnum>" and like "prefix.<fixnum>"; there
should be no need to do anything more.
How do I handle repeated patterns?
Some level of cheating could be allowed, eg. matching (\([^{]*\)) to
colorize with font-lock-variable-name-face (including the spaces), but I
think it won't scale very well.

Quickly enough you reach the point where regexps are the problem.

Instead, you can use a function to do the parsing.

In addition, since parsing would reveal a variable number of elements to
fontify in the same face, that functions would have to do the
fontification itself too.

It can still hook to the font-lock-keywords, if it returns a list of a
single dummy match region. I guess it is used by font-lock to determine
when a region as been font-locked so it doesn't try other matches on it.


For example, see asm7090-font-lock and search-asm7090-fields:
https://gitorious.org/com-informatimago/emacs/source/pjb-asm7090.el
--
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ? C'est le moment d'acheter !"
Loading...