emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r110895: * lisp/progmodes/ruby-mode.e


From: Dmitry Gutov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110895: * lisp/progmodes/ruby-mode.el
Date: Wed, 14 Nov 2012 16:17:21 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110895
committer: Dmitry Gutov <address@hidden>
branch nick: trunk
timestamp: Wed 2012-11-14 16:17:21 +0400
message:
  * lisp/progmodes/ruby-mode.el
  (ruby-syntax-propertize-function): After everything else, search
  for expansions in string literals, mark their insides as
  whitespace syntax and save match data for font-lock.
  (ruby-font-lock-keywords): Highlight just the 2nd group from
  expression expansion matches.
  (ruby-match-expression-expansion): Use the match data saved to the
  text property in ruby-syntax-propertize-function.
  
  * test/automated/ruby-mode-tests.el
  Change direct font-lock face references to var references.
  (ruby-interpolation-suppresses-syntax-inside): New test.
  (ruby-interpolation-inside-percent-literal-with-paren): New
  failing test.
modified:
  lisp/ChangeLog
  lisp/progmodes/ruby-mode.el
  test/ChangeLog
  test/automated/ruby-mode-tests.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-11-14 06:34:17 +0000
+++ b/lisp/ChangeLog    2012-11-14 12:17:21 +0000
@@ -2,6 +2,15 @@
 
        * progmodes/ruby-mode.el (ruby-expr-beg): Make heredoc detection
        more strict.  Add docstring.
+       (ruby-expression-expansion-re): Extract from
+       `ruby-match-expression-expansion'.
+       (ruby-syntax-propertize-function): After everything else, search
+       for expansions in string literals, mark their insides as
+       whitespace syntax and save match data for font-lock.
+       (ruby-font-lock-keywords): Use the 2nd group from expression
+       expansion matches.
+       (ruby-match-expression-expansion): Use the match data saved to the
+       text property in ruby-syntax-propertize-function.
 
 2012-11-14  Stefan Monnier  <address@hidden>
 

=== modified file 'lisp/progmodes/ruby-mode.el'
--- a/lisp/progmodes/ruby-mode.el       2012-11-14 06:34:17 +0000
+++ b/lisp/progmodes/ruby-mode.el       2012-11-14 12:17:21 +0000
@@ -105,7 +105,10 @@
 (eval-and-compile
   (defconst ruby-here-doc-beg-re
   
"\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
-    "Regexp to match the beginning of a heredoc."))
+  "Regexp to match the beginning of a heredoc.")
+
+  (defconst ruby-expression-expansion-re
+    
"[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)"))
 
 (defun ruby-here-doc-end-match ()
   "Return a regexp to find the end of a heredoc.
@@ -1249,7 +1252,19 @@
           ;; Handle percent literals: %w(), %q{}, etc.
           ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
            (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
-         (point) end))
+         (point) end)
+        (remove-text-properties start end '(ruby-expansion-match-data))
+        (goto-char start)
+        ;; Find all expression expansions and
+        ;; - set the syntax of all text inside to whitespace,
+        ;; - save the match data to a text property, for font-locking later.
+        (while (re-search-forward ruby-expression-expansion-re end 'move)
+          (when (ruby-in-ppss-context-p 'string)
+            (put-text-property (match-beginning 2) (match-end 2)
+                               'syntax-table (string-to-syntax "-"))
+            (put-text-property (match-beginning 2) (1+ (match-beginning 2))
+                               'ruby-expansion-match-data
+                               (match-data)))))
 
       (defun ruby-syntax-propertize-heredoc (limit)
         (let ((ppss (syntax-ppss))
@@ -1582,7 +1597,7 @@
    '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 
font-lock-constant-face)
    ;; expression expansion
    '(ruby-match-expression-expansion
-     0 font-lock-variable-name-face t)
+     2 font-lock-variable-name-face t)
    ;; warn lower camel case
                                         
;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
                                         ;  0 font-lock-warning-face)
@@ -1590,9 +1605,14 @@
   "Additional expressions to highlight in Ruby mode.")
 
 (defun ruby-match-expression-expansion (limit)
-  (when (re-search-forward 
"[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)"
 limit 'move)
-    (or (ruby-in-ppss-context-p 'string)
-        (ruby-match-expression-expansion limit))))
+  (let ((prop 'ruby-expansion-match-data) pos value)
+    (when (and (setq pos (next-single-char-property-change (point) prop
+                                                           nil limit))
+               (> pos (point)))
+      (goto-char pos)
+      (or (and (setq value (get-text-property pos prop))
+               (progn (set-match-data value) t))
+          (ruby-match-expression-expansion limit)))))
 
 ;;;###autoload
 (define-derived-mode ruby-mode prog-mode "Ruby"

=== modified file 'test/ChangeLog'
--- a/test/ChangeLog    2012-11-14 06:34:17 +0000
+++ b/test/ChangeLog    2012-11-14 12:17:21 +0000
@@ -3,6 +3,10 @@
        * automated/ruby-mode-tests.el (ruby-indent-singleton-class): Pass.
        (ruby-indent-inside-heredoc-after-operator)
        (ruby-indent-inside-heredoc-after-space): New tests.
+       Change direct font-lock face references to var references.
+       (ruby-interpolation-suppresses-syntax-inside): New test.
+       (ruby-interpolation-inside-percent-literal-with-paren): New
+       failing test.
 
 2012-11-13  Dmitry Gutov  <address@hidden>
 

=== modified file 'test/automated/ruby-mode-tests.el'
--- a/test/automated/ruby-mode-tests.el 2012-11-14 06:34:17 +0000
+++ b/test/automated/ruby-mode-tests.el 2012-11-14 12:17:21 +0000
@@ -80,7 +80,7 @@
 
 (ert-deftest ruby-heredoc-font-lock ()
   (let ((s "foo <<eos.gsub('^ *', '')"))
-    (ruby-assert-face s 9 'font-lock-string-face)
+    (ruby-assert-face s 9 font-lock-string-face)
     (ruby-assert-face s 10 nil)))
 
 (ert-deftest ruby-singleton-class-no-heredoc-font-lock ()
@@ -262,19 +262,35 @@
     (should (string= "foo do |b|\n  b + 1\nend" (buffer-string)))))
 
 (ert-deftest ruby-recognize-symbols-starting-with-at-character ()
-  (ruby-assert-face ":@abc" 3 'font-lock-constant-face))
+  (ruby-assert-face ":@abc" 3 font-lock-constant-face))
 
 (ert-deftest ruby-hash-character-not-interpolation ()
   (ruby-assert-face "\"This is #{interpolation}\"" 15
-                    'font-lock-variable-name-face)
+                    font-lock-variable-name-face)
   (ruby-assert-face "\"This is \\#{no interpolation} despite the #\""
-                    15 'font-lock-string-face)
-  (ruby-assert-face "address@hidden, not ruby code" 5 'font-lock-comment-face)
+                    15 font-lock-string-face)
+  (ruby-assert-face "address@hidden, not ruby code" 5 font-lock-comment-face)
   (ruby-assert-state "address@hidden, not ruby code" 4 t)
   (ruby-assert-face "# A comment cannot have #{an interpolation} in it"
-                    30 'font-lock-comment-face)
+                    30 font-lock-comment-face)
   (ruby-assert-face "# #{comment}\n \"#{interpolation}\"" 16
-                    'font-lock-variable-name-face))
+                    font-lock-variable-name-face))
+
+(ert-deftest ruby-interpolation-suppresses-syntax-inside ()
+  (let ((s "\"<ul><li>address@hidden(\"</li><li>\")}</li></ul>\""))
+    (ruby-assert-state s 8 nil)
+    (ruby-assert-face s 9 font-lock-string-face)
+    (ruby-assert-face s 10 font-lock-variable-name-face)
+    (ruby-assert-face s 41 font-lock-string-face)))
+
+(ert-deftest ruby-interpolation-inside-percent-literal-with-paren ()
+  :expected-result :failed
+  (let ((s "%(^#{\")\"}^)"))
+    (ruby-assert-face s 3 font-lock-string-face)
+    (ruby-assert-face s 4 font-lock-variable-name-face)
+    (ruby-assert-face s 10 font-lock-string-face)
+    ;; It's confused by the closing paren in the middle.
+    (ruby-assert-state s 8 nil)))
 
 (ert-deftest ruby-add-log-current-method-examples ()
   (let ((pairs '(("foo" . "#foo")


reply via email to

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