emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: font-lock-syntactic-keywords: evaluating arbitrary elisp inside matc


From: Stefan Monnier
Subject: Re: font-lock-syntactic-keywords: evaluating arbitrary elisp inside matchers?
Date: Mon, 24 Sep 2012 21:03:28 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2.50 (gnu/linux)

> 1.    `(,(rx
> 2.        (or (seq (or line-start (not (any "-")))
> 3.                 (group-n 1 "-") "-[" (group-n 5 (0+ "=")))
> 4.            (seq (group-n 3 "[")      (group-n 6 (0+ "="))))

> 5.        "[" (minimal-match (0+ anything)) "]"

> 6.        (or (seq (backref 5) (group-n 2 "]"))
> 7.            (seq (backref 6) (group-n 4 "]"))))

> 8.     (1 "!" nil t) (2 "!" nil t)
> 9.    (3 "|" nil t) (4 "|" nil t))

Here's your problem: the comments/strings you want to match may span
several lines, yet the patterns on font-lock-syntactic-keywords cannot
reliably match more than a single line (because when a line is modified,
font-lock only looked for that pattern in that line, for example).

So you need to do something more like:

For syntax-propertize (which is Emacs-24's successor to
font-lock-syntactic-keywords), I'd use something like:

(defun lua-syntax-propertize (start end)
  (goto-char start)
  (lua-syntax-propertize-string-or-comment-end end)
  (funcall
   (syntax-propertize-rules
    ("\\(?:\\(?:^\\|[^-]\\)\\(-\\)-\\)?\\([\\)=*["
     (1 "< b") ;; Only applied if sub-group1 exists.
     (2 (prog1 (unless (match-beginning 1) (string-to-syntax "|"))
          (lua-syntax-propertize-string-or-comment-end end)))))
   start end))

and then in lua-syntax-propertize-string-or-comment I'd use syntax-ppss
to check the parser state (i.e. determine if I'm in a type-b comment or
delimited-string corresponding to a long-bracket construct as opposed to
some type-a comment or standard string, or plain old code), and if I'm
in one of those long-bracket-constructs, use (nth 8 ppss) to find the
beginning, count the number of = used there, then search for the
matching ]==] pattern and place the matching "> b" or "|" syntax on the
second closing bracket.

This should reliably work even for long-brackets that span many many lines.


        Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]