emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 6e63b3e 2/4: Guard against nested percent literal


From: Dmitry Gutov
Subject: [Emacs-diffs] emacs-25 6e63b3e 2/4: Guard against nested percent literals
Date: Mon, 07 Mar 2016 03:08:21 +0000

branch: emacs-25
commit 6e63b3e997e1ac2fa9b58f0d2edeca3cd83628f2
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>

    Guard against nested percent literals
    
    * lisp/progmodes/ruby-mode.el
    (ruby-syntax-propertize-percent-literal):
    Don't check the syntax status.
    (ruby-syntax-propertize): Check it here.  And also guard against
    being in a larger percent literal.
    
    * test/automated/ruby-mode-tests.el
    (ruby-no-nested-percent-literals): New test.
---
 lisp/progmodes/ruby-mode.el       |   61 +++++++++++++++++++------------------
 test/automated/ruby-mode-tests.el |    8 +++++
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index fa94992..1395828 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1901,7 +1901,10 @@ It will be properly highlighted even when the call omits 
parens.")
             (ruby-syntax-propertize-heredoc end))))
       ;; Handle percent literals: %w(), %q{}, etc.
       ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
-       (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
+       (1 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 1))))
+            ;; Not inside a string, a comment, or a percent literal.
+            (ruby-syntax-propertize-percent-literal end)
+            (string-to-syntax "|")))))
      (point) end)))
 
 (define-obsolete-function-alias
@@ -1944,35 +1947,33 @@ It will be properly highlighted even when the call 
omits parens.")
 
 (defun ruby-syntax-propertize-percent-literal (limit)
   (goto-char (match-beginning 2))
-  ;; Not inside a simple string or comment.
-  (when (eq t (nth 3 (syntax-ppss)))
-    (let* ((op (char-after))
-           (ops (char-to-string op))
-           (cl (or (cdr (aref (syntax-table) op))
-                   (cdr (assoc op '((?< . ?>))))))
-           parse-sexp-lookup-properties)
-      (save-excursion
-        (condition-case nil
-            (progn
-              (if cl              ; Paired delimiters.
-                  ;; Delimiter pairs of the same kind can be nested
-                  ;; inside the literal, as long as they are balanced.
-                  ;; Create syntax table that ignores other characters.
-                  (with-syntax-table (make-char-table 'syntax-table nil)
-                    (modify-syntax-entry op (concat "(" (char-to-string cl)))
-                    (modify-syntax-entry cl (concat ")" ops))
-                    (modify-syntax-entry ?\\ "\\")
-                    (save-restriction
-                      (narrow-to-region (point) limit)
-                      (forward-list))) ; skip to the paired character
-                ;; Single character delimiter.
-                (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
-                                           (regexp-quote ops)) limit nil))
-              ;; Found the closing delimiter.
-              (put-text-property (1- (point)) (point) 'syntax-table
-                                 (string-to-syntax "|")))
-          ;; Unclosed literal, do nothing.
-          ((scan-error search-failed)))))))
+  (let* ((op (char-after))
+         (ops (char-to-string op))
+         (cl (or (cdr (aref (syntax-table) op))
+                 (cdr (assoc op '((?< . ?>))))))
+         parse-sexp-lookup-properties)
+    (save-excursion
+      (condition-case nil
+          (progn
+            (if cl              ; Paired delimiters.
+                ;; Delimiter pairs of the same kind can be nested
+                ;; inside the literal, as long as they are balanced.
+                ;; Create syntax table that ignores other characters.
+                (with-syntax-table (make-char-table 'syntax-table nil)
+                  (modify-syntax-entry op (concat "(" (char-to-string cl)))
+                  (modify-syntax-entry cl (concat ")" ops))
+                  (modify-syntax-entry ?\\ "\\")
+                  (save-restriction
+                    (narrow-to-region (point) limit)
+                    (forward-list))) ; skip to the paired character
+              ;; Single character delimiter.
+              (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
+                                         (regexp-quote ops)) limit nil))
+            ;; Found the closing delimiter.
+            (put-text-property (1- (point)) (point) 'syntax-table
+                               (string-to-syntax "|")))
+        ;; Unclosed literal, do nothing.
+        ((scan-error search-failed))))))
 
 (defun ruby-syntax-propertize-expansion ()
   ;; Save the match data to a text property, for font-locking later.
diff --git a/test/automated/ruby-mode-tests.el 
b/test/automated/ruby-mode-tests.el
index da8d77c..7073f7a 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -461,6 +461,14 @@ VALUES-PLIST is a list with alternating index and value 
elements."
   (ruby-assert-face "%S{foo}" 4 nil)
   (ruby-assert-face "%R{foo}" 4 nil))
 
+(ert-deftest ruby-no-nested-percent-literals ()
+  (ruby-with-temp-buffer "a = %w[b %()]"
+    (syntax-propertize (point))
+    (should (null (nth 8 (syntax-ppss))))
+    (should (eq t (nth 3 (syntax-ppss (1- (point-max))))))
+    (search-backward "[")
+    (should (eq t (nth 3 (syntax-ppss))))))
+
 (ert-deftest ruby-add-log-current-method-examples ()
   (let ((pairs '(("foo" . "#foo")
                  ("C.foo" . ".foo")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]