>From 3a1a36b0b42772f35c70fb7e996ba8fed787e1c2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 15 May 2019 18:51:30 -0400 Subject: [PATCH] Backport sgml-syntax-propertize-rules speedup (Bug#33887) * lisp/textmodes/sgml-mode.el (sgml-syntax-propertize-rules): Reapply 2019-01-17 "* lisp/textmodes/sgml-mode.el: Try and fix bug#33887." taking into account 2019-05-09 "Recognize single quote attribute values in nxml and sgml (Bug#35381)" which means we have to handle single quotes as well. * test/lisp/textmodes/sgml-mode-tests.el (sgml-quote-works): New test. --- lisp/textmodes/sgml-mode.el | 21 +++++++++++++++------ test/lisp/textmodes/sgml-mode-tests.el | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 128e58810e..f8a37c3820 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -347,12 +347,21 @@ sgml-font-lock-keywords ("--[ \t\n]*\\(>\\)" (1 "> b")) ("\\(<\\)[?!]" (1 (prog1 "|>" (sgml-syntax-propertize-inside end)))) - ;; Quotes outside of tags should not introduce strings. - ;; Be careful to call `syntax-ppss' on a position before the one we're - ;; going to change, so as not to need to flush the data we just computed. - ("[\"']" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) - (goto-char (match-end 0))) - (string-to-syntax "."))))))) + ;; Quotes outside of tags should not introduce strings which end up + ;; hiding tags. We used to test every quote and mark it as "." + ;; if it's outside of tags, but there are too many quotes and + ;; the resulting number of calls to syntax-ppss made it too slow + ;; (bug#33887), so we're now careful to leave alone any pair + ;; of quotes that doesn't hold a < or > char, which is the vast majority. + ("\\([\"']\\)[^<>\"']*[<>\"']" + (1 (unless (eq (char-after (match-beginning 1)) (char-before)) + ;; Be careful to call `syntax-ppss' on a position before the one + ;; we're going to change, so as not to need to flush the data we + ;; just computed. + (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) + (goto-char (1- (match-end 0)))) + (string-to-syntax "."))))) + ))) (defun sgml-syntax-propertize (start end) "Syntactic keywords for `sgml-mode'." diff --git a/test/lisp/textmodes/sgml-mode-tests.el b/test/lisp/textmodes/sgml-mode-tests.el index 7318a667b3..8d0bb88163 100644 --- a/test/lisp/textmodes/sgml-mode-tests.el +++ b/test/lisp/textmodes/sgml-mode-tests.el @@ -130,5 +130,19 @@ sgml-with-content (sgml-delete-tag 1) (should (string= "Winter is comin'" (buffer-string))))) +(ert-deftest sgml-tests--quotes-syntax () + (dolist (str '("a\"b c'd" + "a'b c\"d" + "\"a'" + "'a\"" + "\"a'\"" + "'a\"'")) + (with-temp-buffer + (sgml-mode) + (insert str) + ;; Check that last tag is parsed as a tag. + (should (= 1 (car (syntax-ppss (1- (point-max)))))) + (should (= 0 (car (syntax-ppss (point-max)))))))) + (provide 'sgml-mode-tests) ;;; sgml-mode-tests.el ends here -- 2.11.0