* lisp/progmodes/ruby-mode.el (ruby-syntax-methods-before-regexp): New const.
authorDmitry Gutov <dgutov@yandex.ru>
Tue, 14 Aug 2012 12:38:11 +0000 (08:38 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Tue, 14 Aug 2012 12:38:11 +0000 (08:38 -0400)
(ruby-syntax-propertize-function): Use it to recognize regexps.
Don't look at the text after regexp, just use the whitelist.
* test/indent/ruby.rb: Rearrange examples, add new ones.

Fixes: debbugs:6286

lisp/ChangeLog
lisp/progmodes/ruby-mode.el
test/ChangeLog
test/indent/ruby.rb

index db4cc8e..875ab5d 100644 (file)
@@ -10,6 +10,9 @@
        (ruby-syntax-propertize-percent-literal): Only propertize when not
        inside a simple string or comment.  When the literal is unclosed,
        leave the text after it unpropertized.
+       (ruby-syntax-methods-before-regexp): New constant.
+       (ruby-syntax-propertize-function): Use it to recognize regexps.
+       Don't look at the text after regexp, just use the whitelist.
 
 2012-08-14  Andreas Schwab  <schwab@linux-m68k.org>
 
index 42e1ac7..457c7fe 100644 (file)
@@ -1178,7 +1178,13 @@ See `add-log-current-defun-function'."
       (eval-and-compile
         (defconst ruby-percent-literal-beg-re
           "\\(%\\)[qQrswWx]?\\([[:punct:]]\\)"
-          "Regexp to match the beginning of percent literal."))
+          "Regexp to match the beginning of percent literal.")
+
+        (defconst ruby-syntax-methods-before-regexp
+          '("gsub" "gsub!" "sub" "sub!" "scan" "split" "split!" "index" "match"
+            "assert_match" "Given" "Then" "When")
+          "Methods that can take regexp as the first argument.
+It will be properly highlighted even when the call omits parens."))
 
       (defun ruby-syntax-propertize-function (start end)
         "Syntactic keywords for Ruby mode.  See `syntax-propertize-function'."
@@ -1196,28 +1202,23 @@ See `add-log-current-defun-function'."
                         ;; Not within a string.
                         (nth 3 (syntax-ppss (match-beginning 0))))
                 (string-to-syntax "\\"))))
-          ;; Regexps: regexps are distinguished from division either because
-          ;; of the keyword/symbol before them, or because of the code
-          ;; following them.
+          ;; Regexps: regexps are distinguished from division because
+          ;; of the keyword, symbol, or method name before them.
           ((concat
             ;; Special tokens that can't be followed by a division operator.
-            "\\(?:\\(^\\|[[=(,~?:;<>]\\|\\(?:^\\|\\s \\)"
+            "\\(^\\|[[=(,~?:;<>]"
+            ;; Control flow keywords and operators following bol or whitespace.
+            "\\|\\(?:^\\|\\s \\)"
             (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and"
-                          "or" "&&" "||"
-                          "gsub" "gsub!" "sub" "sub!" "scan" "split" "split!"))
-            "\\)\\s *\\)?"
+                          "or" "not" "&&" "||"))
+            ;; Method name from the list.
+            "\\|\\_<"
+            (regexp-opt ruby-syntax-methods-before-regexp)
+            "\\)\\s *"
             ;; The regular expression itself.
-            "\\(/\\)[^/\n\\\\]*\\(?:\\\\.[^/\n\\\\]*\\)*\\(/\\)"
-            ;; Special code that cannot follow a division operator.
-            ;; FIXME: Just because the second slash of "/foo/ do bar" can't
-            ;; be a division, doesn't mean it can't *start* a regexp, as in
-            ;; "x = toto/foo; if /do bar/".
-            "\\([imxo]*\\s *\\(?:,\\|\\_<do\\_>\\)\\)?")
-           (2 (when (or (match-beginning 1) (match-beginning 4))
-                (string-to-syntax "\"/")))
-           (3 (if (or (match-beginning 1) (match-beginning 4))
-                  (string-to-syntax "\"/")
-                (goto-char (match-end 2)))))
+            "\\(/\\)[^/\n\\\\]*\\(?:\\\\.[^/\n\\\\]*\\)*\\(/\\)")
+           (2 (string-to-syntax "\"/"))
+           (3 (string-to-syntax "\"/")))
           ("^=en\\(d\\)\\_>" (1 "!"))
           ("^\\(=\\)begin\\_>" (1 "!"))
           ;; Handle here documents.
index a0163b5..f1bf458 100644 (file)
@@ -1,3 +1,7 @@
+2012-08-14  Dmitry Gutov  <dgutov@yandex.ru>
+
+       * indent/ruby.rb: Rearrange examples, add new ones.
+
 2012-08-12  Dmitry Gutov  <dgutov@yandex.ru>
 
        * automated/ruby-mode-tests.el (ruby-move-to-block-stops-at-opening)
index c4a747a..4f2e9e6 100644 (file)
@@ -1,17 +1,25 @@
-# Don't mis-match "sub" at the end of words.
-a = asub / aslb + bsub / bslb;
-
+# Percent literals.
 b = %Q{This is a "string"}
-c = %w(foo
+c = %w!foo
  bar
- baz)
-d = %!hello!
+ baz!
+d = %(hello (nested) world)
+
+# Don't propertize percent literals inside strings.
+"(%s, %s)" % [123, 456]
+
+# Or inside comments.
+x = # "tot %q/to"; =
+y = 2 / 3
+
+# Regexp after whitelisted method.
+"abc".sub /b/, 'd'
+
+# Don't mis-match "sub" at the end of words.
+a = asub / aslb + bsub / bslb;
 
-# A "do" after a slash means that slash is not a division, but it doesn't imply
-# it's a regexp-ender, since it can be a regexp-starter instead!
-x = toto / foo; if /do bar/ then
-                  toto = 1
-                end
+# Highlight the regexp after "if".
+x = toto / foo if /do bar/ =~ "dobar"
 
 # Some Cucumber code:
 Given /toto/ do