I want to write a mode for the Cadabra 2 computer algebra system, which has Python-like syntax, with an exception of having the hash character #
as a wild card in expressions, in addition to being a comment starter like in regular Python. Consider the following code:
\dalembert{ A?? }::LaTeXForm(\Box A??).
{ \mu, \nu }::Indices(vector).
\dalembert{#}::Derivative.
\partial{#}::PartialDerivative.
{ A_{\mu} }::Depends(\partial{#}).
# QED Lagrangian
lagrangian:= (a/2) A_{\mu} \dalembert{ A_{\mu} }
+ (b/2) A_{\mu} \partial_{\nu}{\partial_{\mu}{ A_{\nu} }}
+ (1/2) m**2 A_{\mu} * A^{\mu};
Here, the QED Lagrangian
line is a comment, but }::Derivative.
is not. I want Emacs to interpret #
as a comment delimiter only if it is not enclosed by curly or regular braces, and am struggling to implement that. The way I believe it should be done is with the syntax propertization function:
;;;###autoload
(define-derived-mode my-cadabra2-mode python-mode "cadabra2 mode"
"Major mode for Cadabra 2 computer algebra system"
(setq-local font-lock-defaults '((my-cadabra2-font-lock-keywords)))
(setq-local syntax-propertize-function
(syntax-propertize-rules ("\\(?<!{\s*\\)#\\(?!\s*}\\)" (1 "< ")))))
I believe my regular expression is correct, it should match #
if not preceded by {
and not followed by }
with any whitespace in between. Emacs still uses any hash as a comment starter however.
How do I implement this properly?
*scratch*
buffer gives an(invalid-regexp)
in your argument tosyntax-propetize-rules
.\s
to match whitespace. You want\s-
instead. See emacswiki.org/emacs/RegularExpression for a good primer on emacs regexes.(rx (and "#" (not "}")))
which evaluates just fine and should catch the non-comments in the provided example, but still does not work when I load a file with the mode