Package: emacs;
Reported by: Vincent Lefevre <vincent <at> vinc17.net>
Date: Tue, 4 Jun 2019 15:06:01 UTC
Severity: normal
Tags: fixed
Found in version 27.0.50
Done: Noam Postavsky <npostavs <at> gmail.com>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Noam Postavsky <npostavs <at> gmail.com> Cc: Vincent Lefevre <vincent <at> vinc17.net>, 36092 <at> debbugs.gnu.org Subject: bug#36092: 27.0.50; incorrect highlighting in nXML mode with ' and raw > characters Date: Tue, 04 Jun 2019 21:48:19 -0400
> It's hitting an assertion failure during syntax-propertizing. The > problem seems to be that the parse-partial-sexp call in > sgml--syntax-propertize-ppss isn't using the right syntax table. Hmm... > (defun sgml-syntax-propertize (start end) > "Syntactic keywords for `sgml-mode'." > - (setq sgml--syntax-propertize-ppss (cons start (syntax-ppss start))) > - (cl-assert (>= (cadr sgml--syntax-propertize-ppss) 0)) > - (sgml-syntax-propertize-inside end) > - (funcall > - (syntax-propertize-rules sgml-syntax-propertize-rules) > - start end) > - ;; Catch any '>' after the last quote. > - (sgml--syntax-propertize-ppss end)) > + (with-syntax-table syntax-ppss-table > + (setq sgml--syntax-propertize-ppss (cons start (syntax-ppss start))) > + (cl-assert (>= (cadr sgml--syntax-propertize-ppss) 0)) > + (sgml-syntax-propertize-inside end) > + (funcall > + (syntax-propertize-rules sgml-syntax-propertize-rules) > + start end) > + ;; Catch any '>' after the last quote. > + (sgml--syntax-propertize-ppss end))) OMG! We use syntax-ppss-table in syntax-ppss but not in syntax-propertize! How dumb could I be! Of course, it usually works fine because syntax-propertize is usually called from syntax-ppss, but ... well ... not always, I just install the patch below into `master` to address that. Stefan diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index 9c6d5b5829..b6cba44e77 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el @@ -283,6 +283,9 @@ syntax-propertize-via-font-lock ;; In case it was eval'd/compiled. (setq keywords font-lock-syntactic-keywords))))) +(defvar-local syntax-ppss-table nil + "Syntax-table to use during `syntax-ppss', if any.") + (defun syntax-propertize (pos) "Ensure that syntax-table properties are set until POS (a buffer point)." (when (< syntax-propertize--done pos) @@ -301,47 +304,48 @@ syntax-propertize #'syntax-ppss-flush-cache 99 t)) (save-excursion (with-silent-modifications - (make-local-variable 'syntax-propertize--done) ;Just in case! - (let* ((start (max (min syntax-propertize--done (point-max)) - (point-min))) - (end (max pos - (min (point-max) - (+ start syntax-propertize-chunk-size)))) - (funs syntax-propertize-extend-region-functions)) - (while funs - (let ((new (funcall (pop funs) start end)) - ;; Avoid recursion! - (syntax-propertize--done most-positive-fixnum)) - (if (or (null new) - (and (>= (car new) start) (<= (cdr new) end))) - nil - (setq start (car new)) - (setq end (cdr new)) - ;; If there's been a change, we should go through the - ;; list again since this new position may - ;; warrant a different answer from one of the funs we've - ;; already seen. - (unless (eq funs - (cdr syntax-propertize-extend-region-functions)) - (setq funs syntax-propertize-extend-region-functions))))) - ;; Flush ppss cache between the original value of `start' and that - ;; set above by syntax-propertize-extend-region-functions. - (syntax-ppss-flush-cache start) - ;; Move the limit before calling the function, so the function - ;; can use syntax-ppss. - (setq syntax-propertize--done end) - ;; (message "syntax-propertizing from %s to %s" start end) - (remove-text-properties start end - '(syntax-table nil syntax-multiline nil)) - ;; Avoid recursion! - (let ((syntax-propertize--done most-positive-fixnum)) - (funcall syntax-propertize-function start end)))))))) + (with-syntax-table syntax-ppss-table + (make-local-variable 'syntax-propertize--done) ;Just in case! + (let* ((start (max (min syntax-propertize--done (point-max)) + (point-min))) + (end (max pos + (min (point-max) + (+ start syntax-propertize-chunk-size)))) + (funs syntax-propertize-extend-region-functions)) + (while funs + (let ((new (funcall (pop funs) start end)) + ;; Avoid recursion! + (syntax-propertize--done most-positive-fixnum)) + (if (or (null new) + (and (>= (car new) start) (<= (cdr new) end))) + nil + (setq start (car new)) + (setq end (cdr new)) + ;; If there's been a change, we should go through the + ;; list again since this new position may + ;; warrant a different answer from one of the funs we've + ;; already seen. + (unless (eq funs + (cdr syntax-propertize-extend-region-functions)) + (setq funs syntax-propertize-extend-region-functions))))) + ;; Flush ppss cache between the original value of `start' and that + ;; set above by syntax-propertize-extend-region-functions. + (syntax-ppss-flush-cache start) + ;; Move the limit before calling the function, so the function + ;; can use syntax-ppss. + (setq syntax-propertize--done end) + ;; (message "syntax-propertizing from %s to %s" start end) + (remove-text-properties start end + '(syntax-table nil syntax-multiline nil)) + ;; Avoid recursion! + (let ((syntax-propertize--done most-positive-fixnum)) + (funcall syntax-propertize-function start end))))))))) ;;; Link syntax-propertize with syntax.c. (defvar syntax-propertize-chunks ;; We're not sure how far we'll go. In my tests, using chunks of 2000 - ;; brings to overhead to something negligible. Passing ‘charpos’ directly + ;; brings the overhead to something negligible. Passing ‘charpos’ directly ;; also works (basically works line-by-line) but results in an overhead which ;; I thought was a bit too high (like around 50%). 2000) @@ -450,9 +454,6 @@ syntax-ppss--update-stats (cl-incf (car pair)) (cl-incf (cdr pair) (- new old)))) -(defvar-local syntax-ppss-table nil - "Syntax-table to use during `syntax-ppss', if any.") - (defun syntax-ppss--data () (if (eq (point-min) 1) (progn
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.