[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/rust-mode 75da3b0 189/486: Merge pull request #89 from Mic
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/rust-mode 75da3b0 189/486: Merge pull request #89 from MicahChalmer/fix-slow-angle-bracket-matching |
Date: |
Sat, 7 Aug 2021 09:25:16 -0400 (EDT) |
branch: elpa/rust-mode
commit 75da3b0508ffd2cbb58f2687a46390bf61d63dd0
Merge: ee564d5 ec3855f
Author: Niko Matsakis <niko@alum.mit.edu>
Commit: Niko Matsakis <niko@alum.mit.edu>
Merge pull request #89 from MicahChalmer/fix-slow-angle-bracket-matching
Fix slow angle bracket matching
---
rust-mode-tests.el | 35 ++++++++++
rust-mode.el | 199 +++++++++++++++++++++++++++--------------------------
2 files changed, 137 insertions(+), 97 deletions(-)
diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index 5312f38..8f25f06 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -1110,6 +1110,41 @@ this_is_not_a_string();)"
(should (equal nil (get-text-property 28 'face))) ;; Semicolon--should not
be part of the string
))
+(ert-deftest font-lock-runaway-raw-string ()
+ (rust-test-font-lock
+ "const Z = r#\"my raw string\";\n// oops this is still in the string"
+ '("const" font-lock-keyword-face
+ "Z" font-lock-type-face
+ "r#\"my raw string\";\n// oops this is still in the string"
font-lock-string-face))
+ )
+
+(ert-deftest font-lock-recognize-closing-raw-string ()
+ (with-temp-buffer
+ (rust-mode)
+ (insert "const foo = r##\"
+1...............................................50
+1...............................................50
+1...............................................50
+1...............195-->\"; let ...................50
+1...............................................50
+1...............................................50
+1...............................................50
+1...............................................50
+1...............................................50
+1......................500......................50
+\"#;
+")
+ (font-lock-fontify-buffer)
+ (goto-char 530)
+ (insert "#")
+ ;; We have now closed the raw string. Check that the whole string is
+ ;; recognized after the change
+ (font-lock-after-change-function (1- (point)) (point) 0)
+ (should (equal 'font-lock-string-face (get-text-property 195 'face))) ;;
The "let"
+ (should (equal 'font-lock-string-face (get-text-property 500 'face))) ;;
The "500"
+ (should (equal nil (get-text-property 531 'face))) ;; The second ";"
+ ))
+
;;; Documentation comments
(ert-deftest font-lock-doc-line-comment-parent ()
diff --git a/rust-mode.el b/rust-mode.el
index e451dfa..9899ad1 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -428,24 +428,18 @@
part of it. Adjusts to include the r[#] of a raw string as
well."
- (let ((orig-beg font-lock-beg)
- (orig-end font-lock-end))
- (cond
- ;; If we are not syntactically fontified yet, we cannot correctly cover
- ;; anything less than the full buffer. The syntactic fontification
- ;; modifies the syntax, so until it's done we can't use the syntax to
- ;; determine what to fontify.
- ((< (or font-lock-syntactically-fontified 0) font-lock-end)
- (setq font-lock-beg 1)
- (setq font-lock-end (buffer-end 1)))
-
- ((let* ((beg-ppss (syntax-ppss font-lock-beg))
- (beg-in-cmnt (and (nth 4 beg-ppss) (nth 8 beg-ppss)))
- (beg-in-str (nth 3 beg-ppss))
- (end-ppss (syntax-ppss font-lock-end))
- (end-in-str (nth 3 end-ppss)))
-
- (when (and beg-in-str (> font-lock-beg (nth 8 beg-ppss)))
+ (save-excursion
+ (let ((orig-beg font-lock-beg)
+ (orig-end font-lock-end))
+
+ (let*
+ ;; It's safe to call `syntax-ppss' here on positions that are
+ ;; already syntactically fontified
+ ((beg-ppss (syntax-ppss font-lock-beg))
+ (beg-in-cmnt (and beg-ppss (nth 4 beg-ppss) (nth 8 beg-ppss)))
+ (beg-in-str (and beg-ppss (nth 3 beg-ppss) (nth 8 beg-ppss))))
+
+ (when (and beg-in-str (>= font-lock-beg beg-in-str))
(setq font-lock-beg (nth 8 beg-ppss))
(while (equal ?# (char-before font-lock-beg))
(setq font-lock-beg (1- font-lock-beg)))
@@ -453,18 +447,24 @@
(setq font-lock-beg (1- font-lock-beg))))
(when (and beg-in-cmnt (> font-lock-beg beg-in-cmnt))
- (setq font-lock-beg beg-in-cmnt))
-
- (when end-in-str
- (save-excursion
- (goto-char (nth 8 end-ppss))
- (ignore-errors (forward-sexp))
- (setq font-lock-end (max font-lock-end (point)))))
- )))
-
- (or (/= font-lock-beg orig-beg)
- (/= font-lock-end orig-end))
- ))
+ (setq font-lock-beg beg-in-cmnt)))
+
+ ;; We need to make sure that if the region ends inside a raw string, we
+ ;; extend it out past the end of it. But we can't use `syntax-ppss' to
+ ;; detect that, becaue that depends on font-lock already being done, and
we
+ ;; are trying to figure out how much to font-lock before that. So we use
+ ;; the regexp directly.
+ (save-match-data
+ (goto-char font-lock-beg)
+ (while (and (< (point) font-lock-end)
+ (re-search-forward rust-re-non-standard-string (buffer-end
1) t)
+ (<= (match-beginning 0) font-lock-end))
+ (setq font-lock-end (max font-lock-end (match-end 0)))
+ (goto-char (1+ (match-beginning 0)))))
+
+ (or (/= font-lock-beg orig-beg)
+ (/= font-lock-end orig-end))
+ )))
(defun rust-conditional-re-search-forward (regexp bound condition)
;; Search forward for regexp (with bound). If found, call condition and
return the found
@@ -492,77 +492,82 @@
(set-match-data (nth 1 ret-list))
(nth 0 ret-list))))
+(defconst rust-re-non-standard-string
+ (rx
+ (or
+ ;; Raw string: if it matches, it ends up with the starting character
+ ;; of the string as group 1, any ending backslashes as group 4, and
+ ;; the ending character as either group 5 or group 6.
+ (seq
+ ;; The "r" starts the raw string. Capture it as group 1 to mark it as
such syntactically:
+ (group "r")
+
+ ;; Then either:
+ (or
+ ;; a sequence at least one "#" (followed by quote). Capture all
+ ;; but the last "#" as group 2 for this case.
+ (seq (group (* "#")) "#\"")
+
+ ;; ...or a quote without any "#". Capture it as group 3. This is
+ ;; used later to match the opposite quote only if this capture
+ ;; occurred
+ (group "\""))
+
+ ;; The contents of the string:
+ (*? anything)
+
+ ;; If there are any backslashes at the end of the string, capture
+ ;; them as group 4 so we can suppress the normal escape syntax
+ ;; parsing:
+ (group (* "\\"))
+
+ ;; Then the end of the string--the backreferences ensure that we
+ ;; only match the kind of ending that corresponds to the beginning
+ ;; we had:
+ (or
+ ;; There were "#"s - capture the last one as group 5 to mark it as
+ ;; the end of the string:
+ (seq "\"" (backref 2) (group "#"))
+
+ ;; No "#"s - capture the ending quote (using a backref to group 3,
+ ;; so that we can't match a quote if we had "#"s) as group 6
+ (group (backref 3))
+
+ ;; If the raw string wasn't actually closed, go all the way to the end
+ string-end))
+
+ ;; Character literal: match the beginning ' of a character literal
+ ;; as group 7, and the ending one as group 8
+ (seq
+ (group "'")
+ (or
+ (seq
+ "\\"
+ (or
+ (: "U" (= 8 xdigit))
+ (: "u" (= 4 xdigit))
+ (: "x" (= 2 xdigit))
+ (any "'nrt0\"\\")))
+ (not (any "'\\"))
+ )
+ (group "'"))
+ )
+ ))
+
(defun rust-look-for-non-standard-string (bound)
;; Find a raw string or character literal, but only if it's not in the middle
;; of another string or a comment.
- (let* ((non-standard-str-regexp
- (rx
- (or
- ;; Raw string: if it matches, it ends up with the starting
character
- ;; of the string as group 1, any ending backslashes as group 4, and
- ;; the ending character as either group 5 or group 6.
- (seq
- ;; The "r" starts the raw string. Capture it as group 1 to mark
it as such syntactically:
- (group "r")
-
- ;; Then either:
- (or
- ;; a sequence at least one "#" (followed by quote). Capture all
- ;; but the last "#" as group 2 for this case.
- (seq (group (* "#")) "#\"")
-
- ;; ...or a quote without any "#". Capture it as group 3. This is
- ;; used later to match the opposite quote only if this capture
- ;; occurred
- (group "\""))
-
- ;; The contents of the string:
- (*? anything)
-
- ;; If there are any backslashes at the end of the string, capture
- ;; them as group 4 so we can suppress the normal escape syntax
- ;; parsing:
- (group (* "\\"))
-
- ;; Then the end of the string--the backreferences ensure that we
- ;; only match the kind of ending that corresponds to the beginning
- ;; we had:
- (or
- ;; There were "#"s - capture the last one as group 5 to mark it
as
- ;; the end of the string:
- (seq "\"" (backref 2) (group "#"))
-
- ;; No "#"s - capture the ending quote (using a backref to group
3,
- ;; so that we can't match a quote if we had "#"s) as group 6
- (group (backref 3))))
-
- ;; Character literal: match the beginning ' of a character literal
- ;; as group 7, and the ending one as group 8
- (seq
- (group "'")
- (or
- (seq
- "\\"
- (or
- (: "U" (= 8 xdigit))
- (: "u" (= 4 xdigit))
- (: "x" (= 2 xdigit))
- (any "'nrt0\"\\")))
- (not (any "'\\"))
- )
- (group "'"))
- )
- )))
- (rust-conditional-re-search-forward
- non-standard-str-regexp bound
- (lambda ()
- (let ((pstate (syntax-ppss (match-beginning 0))))
- (not
- (or
- (nth 4 pstate) ;; Skip if in a comment
- (and (nth 3 pstate) (wholenump (nth 8 pstate)) (< (nth 8 pstate)
(match-beginning 0))) ;; Skip if in a string that isn't starting here
- )))))))
+ (rust-conditional-re-search-forward
+ rust-re-non-standard-string
+ bound
+ (lambda ()
+ (let ((pstate (syntax-ppss (match-beginning 0))))
+ (not
+ (or
+ (nth 4 pstate) ;; Skip if in a comment
+ (and (nth 3 pstate) (wholenump (nth 8 pstate)) (< (nth 8 pstate)
(match-beginning 0))) ;; Skip if in a string that isn't starting here
+ ))))))
(defun rust-syntax-class-before-point ()
(when (> (point) 1)
- [nongnu] elpa/rust-mode 2e800ee 151/486: workaround emacs 23 issues., (continued)
- [nongnu] elpa/rust-mode 2e800ee 151/486: workaround emacs 23 issues., ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 2be934c 147/486: Merge pull request #55 from kriben/master, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 4e938b1 164/486: Merge pull request #63 from krig/panic-compilation-warning, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode f17e11a 162/486: Match panics during build as compilation warnings, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode b4ff35c 168/486: remove rust-mode-character-literal-syntax-table, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 5ed4675 171/486: Merge pull request #73 from MicahChalmer/raw-string-multiline-edit-fix, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 9d773b4 170/486: Fix multi-line raw strings when editing, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 6bc1540 186/486: Support nested block comments, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 7baae9c 180/486: Merge pull request #78 from tromey/fix-issue-33, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode c0e3878 183/486: Merge pull request #81 from MicahChalmer/fix-issue-80, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 75da3b0 189/486: Merge pull request #89 from MicahChalmer/fix-slow-angle-bracket-matching,
ELPA Syncer <=
- [nongnu] elpa/rust-mode a2e9f56 199/486: Merge pull request #84 from birkenfeld/compilation-note, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 92584c3 209/486: Fix the special case for the first line, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode b76e803 208/486: Correctly indent where clauses, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 304ae4b 219/486: Change font-lock face for module names., ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode ae49380 221/486: Merge pull request #121 from fbergroth/integrate-rustfmt, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 315cc59 233/486: Re-indent on }, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode bc77e16 240/486: remove emacs 23 support, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 620d718 257/486: Fix #160, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode cffb950f2 258/486: [master] Remove redundant progn., ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode b3b0f78 259/486: Merge pull request #161 from Fanael/master, ELPA Syncer, 2021/08/07