diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4f52796..f37c346 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -9,6 +9,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-13 Andreas Schwab diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 42e1ac7..457c7fe 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -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 *\\(?:,\\|\\_\\)\\)?") - (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. diff --git a/test/ChangeLog b/test/ChangeLog index 9dbca3d..f1bf458 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,6 +1,6 @@ 2012-08-14 Dmitry Gutov - * indent/ruby.rb: New examples. + * indent/ruby.rb: Rearrange examples, add new ones. 2012-08-12 Dmitry Gutov diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index 7a9d123..4f2e9e6 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -1,24 +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] -# Nor inside comments. +# Or inside comments. x = # "tot %q/to"; = y = 2 / 3 -# 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 +# Regexp after whitelisted method. +"abc".sub /b/, 'd' + +# Don't mis-match "sub" at the end of words. +a = asub / aslb + bsub / bslb; + +# Highlight the regexp after "if". +x = toto / foo if /do bar/ =~ "dobar" # Some Cucumber code: Given /toto/ do