aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2019-05-26 11:07:14 -0400
committerNoam Postavsky2019-06-04 08:42:50 -0400
commit438e4804d107720f526d0c7c367cbd029f264676 (patch)
tree3b8a3561bc86f6a67a65d918c1f064e21445cbd0
parent7aaf500701be3b51c686b7d86c9b505ef5fa9b8f (diff)
downloademacs-438e4804d107720f526d0c7c367cbd029f264676.tar.gz
emacs-438e4804d107720f526d0c7c367cbd029f264676.zip
Fix some SGML syntax edge cases (Bug#33887)
* lisp/textmodes/sgml-mode.el (sgml-syntax-propertize-rules): Handle single and double quotes symmetrically. Don't skip quoted comment enders. * test/lisp/textmodes/sgml-mode-tests.el (sgml-tests--quotes-syntax): Add more test cases. (sgml-mode-quote-in-long-text): New test.
-rw-r--r--lisp/textmodes/sgml-mode.el5
-rw-r--r--test/lisp/textmodes/sgml-mode-tests.el45
2 files changed, 42 insertions, 8 deletions
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index 75f20722b05..1df7e78afc5 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -363,9 +363,12 @@ Any terminating `>' or `/' is not matched.")
363 ;; the resulting number of calls to syntax-ppss made it too slow 363 ;; the resulting number of calls to syntax-ppss made it too slow
364 ;; (bug#33887), so we're now careful to leave alone any pair 364 ;; (bug#33887), so we're now careful to leave alone any pair
365 ;; of quotes that doesn't hold a < or > char, which is the vast majority. 365 ;; of quotes that doesn't hold a < or > char, which is the vast majority.
366 ("\\(?:\\(?1:\"\\)[^\"<>]*\\|\\(?1:'\\)[^'\"<>]*\\)" 366 ("\\([\"']\\)[^\"'<>]*"
367 (1 (if (eq (char-after) (char-after (match-beginning 0))) 367 (1 (if (eq (char-after) (char-after (match-beginning 0)))
368 (forward-char 1) 368 (forward-char 1)
369 ;; Avoid skipping comment ender.
370 (when (eq (char-after) ?>)
371 (skip-chars-backward "-"))
369 ;; Be careful to call `syntax-ppss' on a position before the one 372 ;; Be careful to call `syntax-ppss' on a position before the one
370 ;; we're going to change, so as not to need to flush the data we 373 ;; we're going to change, so as not to need to flush the data we
371 ;; just computed. 374 ;; just computed.
diff --git a/test/lisp/textmodes/sgml-mode-tests.el b/test/lisp/textmodes/sgml-mode-tests.el
index 1b8965e3440..34d26480a45 100644
--- a/test/lisp/textmodes/sgml-mode-tests.el
+++ b/test/lisp/textmodes/sgml-mode-tests.el
@@ -161,15 +161,46 @@ The point is set to the beginning of the buffer."
161 (should (string= "&&" (buffer-string)))))) 161 (should (string= "&&" (buffer-string))))))
162 162
163(ert-deftest sgml-tests--quotes-syntax () 163(ert-deftest sgml-tests--quotes-syntax ()
164 (dolist (str '("a\"b <t>c'd</t>"
165 "a'b <t>c\"d</t>"
166 "<t>\"a'</t>"
167 "<t>'a\"</t>"
168 "<t>\"a'\"</t>"
169 "<t>'a\"'</t>"
170 "a\"b <tag>c'd</tag>"
171 "<tag>c>'d</tag>"
172 "<t><!-- \" --></t>"
173 "<t><!-- ' --></t>"
174 ))
175 (with-temp-buffer
176 (sgml-mode)
177 (insert str)
178 (ert-info ((format "%S" str) :prefix "Test case: ")
179 ;; Check that last tag is parsed as a tag.
180 (should (= 1 (car (syntax-ppss (1- (point-max))))))
181 (should (= 0 (car (syntax-ppss (point-max)))))))))
182
183(ert-deftest sgml-mode-quote-in-long-text ()
164 (with-temp-buffer 184 (with-temp-buffer
165 (sgml-mode) 185 (sgml-mode)
166 (insert "a\"b <tag>c'd</tag>") 186 (insert "<t>"
167 (should (= 1 (car (syntax-ppss (1- (point-max)))))) 187 ;; `syntax-propertize-wholelines' extends chunk size based
168 (should (= 0 (car (syntax-ppss (point-max))))) 188 ;; on line length, so newlines are significant!
169 (erase-buffer) 189 (make-string syntax-propertize-chunk-size ?a) "\n"
170 (insert "<tag>c>d</tag>") 190 "'"
171 (should (= 1 (car (syntax-ppss (1- (point-max)))))) 191 (make-string syntax-propertize-chunk-size ?a) "\n"
172 (should (= 0 (car (syntax-ppss (point-max))))))) 192 "</t>")
193 ;; If we just check (syntax-ppss (point-max)) immediately, then
194 ;; we'll end up propertizing the whole buffer in one chunk (so the
195 ;; test is useless). Simulate something more like what happens
196 ;; when the buffer is viewed normally.
197 (cl-loop for pos from (point-min) to (point-max)
198 by syntax-propertize-chunk-size
199 do (syntax-ppss pos))
200 (syntax-ppss (point-max))
201 ;; Check that last tag is parsed as a tag.
202 (should (= 1 (- (car (syntax-ppss (1- (point-max))))
203 (car (syntax-ppss (point-max))))))))
173 204
174(provide 'sgml-mode-tests) 205(provide 'sgml-mode-tests)
175;;; sgml-mode-tests.el ends here 206;;; sgml-mode-tests.el ends here