Allow back-references in syntax-propertize-rules.

* lisp/emacs-lisp/syntax.el (syntax-propertize--shift-groups-and-backrefs):
Renamed from syntax-propertize--shift-groups, and also shift
back-references.
(syntax-propertize-rules): Adapt docstring and use renamed function.
* test/lisp/emacs-lisp/syntax-tests.el: New test.
(syntax-propertize--shift-groups-and-backrefs): New ERT test.
This commit is contained in:
Tassilo Horn 2020-05-16 10:05:12 +02:00
parent 659ed857c0
commit 5af991872d
2 changed files with 92 additions and 10 deletions

View file

@ -139,14 +139,28 @@ delimiter or an Escaped or Char-quoted character."))
(point-max))))
(cons beg end))
(defun syntax-propertize--shift-groups (re n)
(replace-regexp-in-string
"\\\\(\\?\\([0-9]+\\):"
(lambda (s)
(replace-match
(number-to-string (+ n (string-to-number (match-string 1 s))))
t t s 1))
re t t))
(defun syntax-propertize--shift-groups-and-backrefs (re n)
(let ((new-re (replace-regexp-in-string
"\\\\(\\?\\([0-9]+\\):"
(lambda (s)
(replace-match
(number-to-string
(+ n (string-to-number (match-string 1 s))))
t t s 1))
re t t))
(pos 0))
(while (string-match "\\\\\\([0-9]+\\)" new-re pos)
(setq pos (+ 1 (match-beginning 1)))
(when (save-match-data
;; With \N, the \ must be in a subregexp context, i.e.,
;; not in a character class or in a \{\} repetition.
(subregexp-context-p new-re (match-beginning 0)))
(let ((shifted (+ n (string-to-number (match-string 1 new-re)))))
(when (> shifted 9)
(error "There may be at most nine back-references"))
(setq new-re (replace-match (number-to-string shifted)
t t new-re 1)))))
new-re))
(defmacro syntax-propertize-precompile-rules (&rest rules)
"Return a precompiled form of RULES to pass to `syntax-propertize-rules'.
@ -190,7 +204,8 @@ for subsequent HIGHLIGHTs.
Also SYNTAX is free to move point, in which case RULES may not be applied to
some parts of the text or may be applied several times to other parts.
Note: back-references in REGEXPs do not work."
Note: There may be at most nine back-references in the REGEXPs of
all RULES in total."
(declare (debug (&rest &or symbolp ;FIXME: edebug this eval step.
(form &rest
(numberp
@ -219,7 +234,7 @@ Note: back-references in REGEXPs do not work."
;; tell when *this* match 0 has succeeded.
(cl-incf offset)
(setq re (concat "\\(" re "\\)")))
(setq re (syntax-propertize--shift-groups re offset))
(setq re (syntax-propertize--shift-groups-and-backrefs re offset))
(let ((code '())
(condition
(cond