]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/progmodes/ruby-mode.el (ruby-syntax-propertize-function):
authorDmitry Gutov <dgutov@yandex.ru>
Fri, 14 Dec 2012 06:58:15 +0000 (10:58 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Fri, 14 Dec 2012 06:58:15 +0000 (10:58 +0400)
Extract `ruby-syntax-propertize-expansions'.
(ruby-syntax-propertize-expansions): Only change syntax on
certain string delimiters, to punctuation.  This way the common
functions like forward-word and thing-at-point still work.
(ruby-match-expression-expansion): Improve readability.
(ruby-block-contains-point): New function.
(ruby-add-log-current-method): Handle several edge cases.

* test/automated/ruby-mode-tests.el
Rename one interpolation test; add three more.
(ruby-with-temp-buffer): New macro, use it where appropriate.
(ruby-add-log-current-method-examples): Use "_" for target point.
Add four tests for ruby-add-log-current-method.

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

index 2d12a357cbf42dfb3ad65e7bf60ca9093b59e9bf..8df55eaa1086fdf5f4fbd5b0c29b45d179ed8a9a 100644 (file)
@@ -6,6 +6,8 @@
        certain string delimiters, to punctuation.  This way the common
        functions like forward-word and thing-at-point still work.
        (ruby-match-expression-expansion): Improve readability.
+       (ruby-block-contains-point): New function.
+       (ruby-add-log-current-method): Handle several edge cases.
 
 2012-12-13  Juanma Barranquero  <lekktu@gmail.com>
 
index 6b9e921be671303716a88cf3505199cdb88cd9e8..8ac2f659058ea69c5ea0e6bd186a7f104146df25 100644 (file)
   '"\\(def\\|class\\|module\\)"
   "Regexp to match the beginning of a defun, in the general sense.")
 
+(defconst ruby-singleton-class-re
+  "class\\s *<<"
+  "Regexp to match the beginning of a singleton class context.")
+
 (eval-and-compile
   (defconst ruby-here-doc-beg-re
   "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
@@ -384,7 +388,7 @@ and `\\' when preceded by `?'."
     (when pos (goto-char pos))
     (forward-word -1)
     (and (or (bolp) (not (eq (char-before (point)) ?_)))
-         (looking-at "class\\s *<<"))))
+         (looking-at ruby-singleton-class-re))))
 
 (defun ruby-expr-beg (&optional option)
   "Check if point is possibly at the beginning of an expression.
@@ -1057,35 +1061,32 @@ For example:
 See `add-log-current-defun-function'."
   (condition-case nil
       (save-excursion
-        (let (mname mlist (indent 0))
+        (let ((indent 0) mname mlist
+              (start (point))
+              (definition-re
+                (concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
+                        "\\("
+                        ;; \\. and :: for class methods
+                        "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
+                        "+\\)")))
           ;; Get the current method definition (or class/module).
-          (if (re-search-backward
-               (concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
-                       "\\("
-                       ;; \\. and :: for class methods
-                       "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
-                       "+\\)")
-               nil t)
-              (progn
-                (setq mname (match-string 2))
-                (unless (string-equal "def" (match-string 1))
-                  (setq mlist (list mname) mname nil))
-                (goto-char (match-beginning 1))
-                (setq indent (current-column))
-                (beginning-of-line)))
+          (when (re-search-backward definition-re nil t)
+            (goto-char (match-beginning 1))
+            (when (ruby-block-contains-point start)
+              ;; We're inside the method, class or module.
+              (setq mname (match-string 2))
+              (unless (string-equal "def" (match-string 1))
+                (setq mlist (list mname) mname nil)))
+            (setq indent (current-column))
+            (beginning-of-line))
           ;; Walk up the class/module nesting.
           (while (and (> indent 0)
-                      (re-search-backward
-                       (concat
-                        "^[ \t]*\\(class\\|module\\)[ \t]+"
-                        "\\([A-Z]" ruby-symbol-re "*\\)")
-                       nil t))
+                      (re-search-backward definition-re nil t))
             (goto-char (match-beginning 1))
-            (if (< (current-column) indent)
-                (progn
-                  (setq mlist (cons (match-string 2) mlist))
-                  (setq indent (current-column))
-                  (beginning-of-line))))
+            (when (ruby-block-contains-point start)
+              (setq mlist (cons (match-string 2) mlist))
+              (setq indent (current-column))
+              (beginning-of-line)))
           ;; Process the method name.
           (when mname
             (let ((mn (split-string mname "\\.\\|::")))
@@ -1104,7 +1105,14 @@ See `add-log-current-defun-function'."
                           (setcdr (last mlist) (butlast mn))
                         (setq mlist (butlast mn))))
                     (setq mname (concat "." (car (last mn)))))
-                (setq mname (concat "#" mname)))))
+                ;; See if the method is in singleton class context.
+                (let ((in-singleton-class
+                       (when (re-search-forward ruby-singleton-class-re start t)
+                         (goto-char (match-beginning 0))
+                         (ruby-block-contains-point start))))
+                  (setq mname (concat
+                               (if in-singleton-class "." "#")
+                               mname))))))
           ;; Generate the string.
           (if (consp mlist)
               (setq mlist (mapconcat (function identity) mlist "::")))
@@ -1112,6 +1120,12 @@ See `add-log-current-defun-function'."
               (if mlist (concat mlist mname) mname)
             mlist)))))
 
+(defun ruby-block-contains-point (pt)
+  (save-excursion
+    (save-match-data
+      (ruby-forward-sexp)
+      (> (point) pt))))
+
 (defun ruby-brace-to-do-end (orig end)
   (let (beg-marker end-marker)
     (goto-char end)
index ccebdda7411d83ad3943ae066b7097aa08beec28..e7e7c755d02da538439a41abb1a052cb2bb05227 100644 (file)
@@ -2,6 +2,9 @@
 
        * automated/ruby-mode-tests.el
        Rename one interpolation test; add three more.
+       (ruby-with-temp-buffer): New macro, use it where appropriate.
+       (ruby-add-log-current-method-examples): Use "_" for target point.
+       Add four new tests for ruby-add-log-current-method.
 
 2012-12-11  Glenn Morris  <rgm@gnu.org>
 
index 6ae23f94f1ae3808ffb4302dad6ae79c71450a2c..1f0c0ab6f9e8cf7c1460c8f9c32c17f4201af522 100644 (file)
@@ -25,9 +25,7 @@
 
 (defun ruby-should-indent (content column)
   "Assert indentation COLUMN on the last line of CONTENT."
-  (with-temp-buffer
-    (insert content)
-    (ruby-mode)
+  (ruby-with-temp-buffer content
     (ruby-indent-line)
     (should (= (current-indentation) column))))
 
   "Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
 
 The whitespace before and including \"|\" on each line is removed."
-  (with-temp-buffer
-    (insert (ruby-test-string content))
-    (ruby-mode)
+  (ruby-with-temp-buffer (ruby-test-string content)
     (indent-region (point-min) (point-max))
     (should (string= (ruby-test-string expected) (buffer-string)))))
 
+(defmacro ruby-with-temp-buffer (contents &rest body)
+  (declare (indent 1) (debug t))
+  `(with-temp-buffer
+     (insert ,contents)
+     (ruby-mode)
+     ,@body))
+
 (defun ruby-test-string (s &rest args)
   (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args))
 
@@ -48,9 +51,7 @@ The whitespace before and including \"|\" on each line is removed."
   "Assert syntax state values at the end of CONTENT.
 
 VALUES-PLIST is a list with alternating index and value elements."
-  (with-temp-buffer
-    (insert content)
-    (ruby-mode)
+  (ruby-with-temp-buffer content
     (syntax-propertize (point))
     (while values-plist
       (should (eq (nth (car values-plist)
@@ -59,9 +60,7 @@ VALUES-PLIST is a list with alternating index and value elements."
       (setq values-plist (cddr values-plist)))))
 
 (defun ruby-assert-face (content pos face)
-  (with-temp-buffer
-    (insert content)
-    (ruby-mode)
+  (ruby-with-temp-buffer content
     (font-lock-fontify-buffer)
     (should (eq face (get-text-property pos 'face)))))
 
@@ -226,17 +225,13 @@ VALUES-PLIST is a list with alternating index and value elements."
    |"))
 
 (ert-deftest ruby-move-to-block-stops-at-indentation ()
-  (with-temp-buffer
-    (insert "def f\nend")
+  (ruby-with-temp-buffer "def f\nend"
     (beginning-of-line)
-    (ruby-mode)
     (ruby-move-to-block -1)
     (should (looking-at "^def"))))
 
 (ert-deftest ruby-toggle-block-to-do-end ()
-  (with-temp-buffer
-    (insert "foo {|b|\n}")
-    (ruby-mode)
+  (ruby-with-temp-buffer "foo {|b|\n}"
     (beginning-of-line)
     (ruby-toggle-block)
     (should (string= "foo do |b|\nend" (buffer-string)))))
@@ -254,9 +249,7 @@ VALUES-PLIST is a list with alternating index and value elements."
           (should (string= (cdr pair) (buffer-string))))))))
 
 (ert-deftest ruby-toggle-block-to-multiline ()
-  (with-temp-buffer
-    (insert "foo {|b| b + 1}")
-    (ruby-mode)
+  (ruby-with-temp-buffer "foo {|b| b + 1}"
     (beginning-of-line)
     (ruby-toggle-block)
     (should (string= "foo do |b|\n  b + 1\nend" (buffer-string)))))
@@ -295,9 +288,8 @@ VALUES-PLIST is a list with alternating index and value elements."
 
 (ert-deftest ruby-interpolation-keeps-non-quote-syntax ()
   (let ((s "\"foo#{baz.tee}bar\""))
-    (with-temp-buffer
-      (save-excursion
-        (insert s))
+    (ruby-with-temp-buffer s
+      (goto-char (point-min))
       (ruby-mode)
       (font-lock-fontify-buffer)
       (search-forward "tee")
@@ -318,21 +310,66 @@ VALUES-PLIST is a list with alternating index and value elements."
                  ("self.foo" . ".foo"))))
     (dolist (pair pairs)
       (let ((name  (car pair))
-           (value (cdr pair)))
-       (with-temp-buffer
-         (insert (ruby-test-string
-                  "module M
-                        |  class C
-                        |    def %s
-                        |    end
-                        |  end
-                        |end"
-                  name))
-         (ruby-mode)
-         (search-backward "def")
-         (forward-line)
-         (should (string= (ruby-add-log-current-method)
-                          (format "M::C%s" value))))))))
+            (value (cdr pair)))
+        (ruby-with-temp-buffer (ruby-test-string
+                                "module M
+                                |  class C
+                                |    def %s
+                                |      _
+                                |    end
+                                |  end
+                                |end"
+                                name)
+          (search-backward "_")
+          (forward-line)
+          (should (string= (ruby-add-log-current-method)
+                           (format "M::C%s" value))))))))
+
+(ert-deftest ruby-add-log-current-method-outside-of-method ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "module M
+                          |  class C
+                          |    def foo
+                          |    end
+                          |    _
+                          |  end
+                          |end")
+    (search-backward "_")
+    (should (string= (ruby-add-log-current-method)"M::C"))))
+
+(ert-deftest ruby-add-log-current-method-in-singleton-class ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "class C
+                          |  class << self
+                          |    def foo
+                          |      _
+                          |    end
+                          |  end
+                          |end")
+    (search-backward "_")
+    (should (string= (ruby-add-log-current-method) "C.foo"))))
+
+(ert-deftest ruby-add-log-current-method-namespace-shorthand ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "class C::D
+                          |  def foo
+                          |    _
+                          |  end
+                          |end")
+    (search-backward "_")
+    (should (string= (ruby-add-log-current-method) "C::D#foo"))))
+
+(ert-deftest ruby-add-log-current-method-after-inner-class ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "module M
+                          |  class C
+                          |    class D
+                          |    end
+                          |    _
+                          |  end
+                          |end")
+    (search-backward "_")
+    (should (string= (ruby-add-log-current-method) "M::C"))))
 
 (defvar ruby-block-test-example
   (ruby-test-string