From f063063a8a8bfc1ba343e7e9eb5d17f866f6fccd Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Tue, 14 Aug 2012 08:38:11 -0400 Subject: [PATCH] * lisp/progmodes/ruby-mode.el (ruby-syntax-methods-before-regexp): New const. (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 | 3 +++ lisp/progmodes/ruby-mode.el | 39 +++++++++++++++++++------------------ test/ChangeLog | 4 ++++ test/indent/ruby.rb | 30 +++++++++++++++++----------- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index db4cc8e7fab..875ab5d3188 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -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 diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 42e1ac72b33..457c7fee36c 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 a0163b56e6d..f1bf458f812 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +2012-08-14 Dmitry Gutov + + * indent/ruby.rb: Rearrange examples, add new ones. + 2012-08-12 Dmitry Gutov * automated/ruby-mode-tests.el (ruby-move-to-block-stops-at-opening) diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index c4a747a1c78..4f2e9e63377 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -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 -- 2.39.2