]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/progmodes/ruby-mode.el (ruby-indent-beg-re): Add pieces from
authorDmitry Gutov <dgutov@yandex.ru>
Fri, 7 Sep 2012 04:15:56 +0000 (08:15 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Fri, 7 Sep 2012 04:15:56 +0000 (08:15 +0400)
ruby-beginning-of-indent, simplify, allow all keywords to have
indentation before them.
(ruby-beginning-of-indent): Adjust for above.  Search until the
found point is not inside a string or comment.
(ruby-font-lock-keywords): Allow symbols to start with "@"
character, give them higher priority than variables.
(ruby-syntax-propertize-function)
(ruby-font-lock-syntactic-keywords): Remove the "not comments"
matchers.  Expression expansions are not comments when inside a
string, and there comment syntax status is irrelevant.
(ruby-match-expression-expansion): New function.  Check that
expression expansion is inside a string, and it's not escaped.
(ruby-font-lock-keywords): Use it.

* test/automated/ruby-mode-tests.el: New tests (Bug#11613).

lisp/ChangeLog
lisp/progmodes/ruby-mode.el
test/ChangeLog
test/automated/ruby-mode-tests.el

index 37064b6680b30b4dce4c1ce65a4e4cb40d92e4e4..2f7dac68467c60af4a25de716b45148da52c3b64 100644 (file)
        Let-bind `isearch-word' to the argument `delimited-flag'.
        (Bug#10885, bug#10887)
 
+2012-09-07  Dmitry Gutov  <dgutov@yandex.ru>
+
+       * progmodes/ruby-mode.el (ruby-indent-beg-re): Add pieces from
+       ruby-beginning-of-indent, simplify, allow all keywords to have
+       indentation before them.
+       (ruby-beginning-of-indent): Adjust for above.  Search until the
+       found point is not inside a string or comment.
+       (ruby-font-lock-keywords): Allow symbols to start with "@"
+       character, give them higher priority than variables.
+       (ruby-syntax-propertize-function)
+       (ruby-font-lock-syntactic-keywords): Remove the "not comments"
+       matchers.  Expression expansions are not comments when inside a
+       string, and there comment syntax status is irrelevant.
+       (ruby-match-expression-expansion): New function.  Check that
+       expression expansion is inside a string, and it's not escaped.
+       (ruby-font-lock-keywords): Use it.
+
 2012-09-05  Martin Rudalics  <rudalics@gmx.at>
 
        * help.el (temp-buffer-max-height): New default value.
index 3f93ffa84baabeddec3042587d7705c1ce41b535..bcebada5e8696453efc6bfa281e64d8f9bb6ab3a 100644 (file)
@@ -64,8 +64,8 @@
   "Regexp to match keywords that nest without blocks.")
 
 (defconst ruby-indent-beg-re
-  (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)\\|"
-          (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin")))
+  (concat "^\\s *" (regexp-opt '("class" "module" "def" "if" "unless" "case"
+                                 "while" "until" "for" "begin")) "\\_>")
   "Regexp to match where the indentation gets deeper.")
 
 (defconst ruby-modifier-beg-keywords
@@ -848,19 +848,18 @@ move forward."
 With ARG, move forward multiple defuns.  Negative ARG means
 move backward."
   (interactive "p")
-  (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\($\\|\\b[^_]\\)")
-                          nil 'move (or arg 1))
+  (and (re-search-forward ruby-indent-beg-re nil 'move (or arg 1))
        (beginning-of-line))
   (forward-line 1))
 
 (defun ruby-beginning-of-indent ()
-  "TODO: document"
-  ;; I don't understand this function.
-  ;; It seems like it should move to the line where indentation should deepen,
-  ;; but ruby-indent-beg-re only accounts for whitespace before class, module and def,
-  ;; so this will only match other block beginners at the beginning of the line.
-  (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\_>") nil 'move)
-       (beginning-of-line)))
+  "Backtrack to a line which can be used as a reference for
+calculating indentation on the lines after it."
+  (while (and (re-search-backward ruby-indent-beg-re nil 'move)
+              (if (ruby-in-ppss-context-p 'anything)
+                  t
+                ;; We can stop, then.
+                (beginning-of-line)))))
 
 (defun ruby-move-to-block (n)
   "Move to the beginning (N < 0) or the end (N > 0) of the current block
@@ -1171,8 +1170,6 @@ It will be properly highlighted even when the call omits parens."))
         (ruby-syntax-enclosing-percent-literal end)
         (funcall
          (syntax-propertize-rules
-          ;; #{ }, #$hoge, #@foo are not comments.
-          ("\\(#\\)[{$@]" (1 "."))
           ;; $' $" $` .... are variables.
           ;; ?' ?" ?` are ascii codes.
           ("\\([?$]\\)[#\"'`]"
@@ -1304,8 +1301,7 @@ This should only be called after matching against `ruby-here-doc-end-re'."
                   (concat "-?\\([\"']\\|\\)" contents "\\1"))))))
 
   (defconst ruby-font-lock-syntactic-keywords
-    `( ;; #{ }, #$hoge, #@foo are not comments
-    ("\\(#\\)[{$@]" 1 (1 . nil))
+    `(
     ;; the last $', $", $` in the respective string is not variable
     ;; the last ?', ?", ?` in the respective string is not ascii code
     ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)"
@@ -1527,6 +1523,9 @@ See `font-lock-syntax-table'.")
    ;; variables
    '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>"
      2 font-lock-variable-name-face)
+   ;; symbols
+   '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
+     2 font-lock-reference-face)
    ;; variables
    '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
      1 font-lock-variable-name-face)
@@ -1535,12 +1534,9 @@ See `font-lock-syntax-table'.")
    ;; constants
    '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
      2 font-lock-type-face)
-   ;; symbols
-   '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
-     2 font-lock-reference-face)
    '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face)
    ;; expression expansion
-   '("#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)"
+   '(ruby-match-expression-expansion
      0 font-lock-variable-name-face t)
    ;; warn lower camel case
                                         ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
@@ -1548,6 +1544,10 @@ See `font-lock-syntax-table'.")
    )
   "Additional expressions to highlight in Ruby mode.")
 
+(defun ruby-match-expression-expansion (limit)
+  (when (re-search-forward "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)" limit 'move)
+    (ruby-in-ppss-context-p 'string)))
+
 ;;;###autoload
 (define-derived-mode ruby-mode prog-mode "Ruby"
   "Major mode for editing Ruby scripts.
index f523f6f59a902451bc47774dd00c3ebebc37dc0f..541937ec4e7b65aa8afb872fb1ef88f83eee7ff0 100644 (file)
@@ -1,3 +1,7 @@
+2012-09-07  Dmitry Gutov  <dgutov@yandex.ru>
+
+       * automated/ruby-mode-tests.el: New tests (Bug#11613).
+
 2012-08-28  Chong Yidong  <cyd@gnu.org>
 
        * automated/files.el: Test every combination of values for
index df51aa0d15a65f9602e28282a2f3ce60db85b290..1adc4acdfa0769d5362a9da5bbe1d2f4e947bc49 100644 (file)
@@ -57,6 +57,13 @@ VALUES-PLIST is a list with alternating index and value elements."
                   (cadr values-plist)))
       (setq values-plist (cddr values-plist)))))
 
+(defun ruby-assert-face (content pos face)
+  (with-temp-buffer
+    (insert content)
+    (ruby-mode)
+    (font-lock-fontify-buffer)
+    (should (eq face (get-text-property pos 'face)))))
+
 (ert-deftest ruby-indent-after-symbol-made-from-string-interpolation ()
   "It can indent the line after symbol made using string interpolation."
   (ruby-should-indent "def foo(suffix)\n  :\"bar#{suffix}\"\n"
@@ -84,6 +91,11 @@ VALUES-PLIST is a list with alternating index and value elements."
     (ruby-should-indent "foo = {\na: b" ruby-indent-level)
     (ruby-should-indent "foo(\na" ruby-indent-level)))
 
+(ert-deftest ruby-indent-after-keyword-in-a-string ()
+  (ruby-should-indent "a = \"abc\nif\"\n  " 0)
+  (ruby-should-indent "a = %w[abc\n       def]\n  " 0)
+  (ruby-should-indent "a = \"abc\n      def\"\n  " 0))
+
 (ert-deftest ruby-indent-simple ()
   (ruby-should-indent-buffer
    "if foo
@@ -217,6 +229,19 @@ VALUES-PLIST is a list with alternating index and value elements."
     (should (string= "foo {|b|\n}\n" (buffer-substring-no-properties
                                       (point-min) (point-max))))))
 
+(ert-deftest ruby-recognize-symbols-starting-with-at-character ()
+  (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)
+  (ruby-assert-face "\"This is \\#{no interpolation} despite the #\""
+                    15 'font-lock-string-face)
+  (ruby-assert-face "#@comment, not ruby code" 3 'font-lock-comment-face)
+  (ruby-assert-state "#@comment, not ruby code" 4 t)
+  (ruby-assert-face "# A comment cannot have #{an interpolation} in it"
+                    30 'font-lock-comment-face))
+
 (provide 'ruby-mode-tests)
 
 ;;; ruby-mode-tests.el ends here