]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix ruby-add-log-current-method after nested class definition
authorDmitry Gutov <dgutov@yandex.ru>
Thu, 15 Dec 2022 01:21:14 +0000 (03:21 +0200)
committerDmitry Gutov <dgutov@yandex.ru>
Thu, 15 Dec 2022 01:21:44 +0000 (03:21 +0200)
* lisp/progmodes/ruby-mode.el (ruby--add-log-current-indent):
New function.
(ruby-add-log-current-method): Use it.
Check for "class" and "module" indentation to filter out the
definitions which don't include the given position.  Also try to
match "def" only once (for performance), because if the closest
one doesn't include the given position, none will.

* test/lisp/progmodes/ruby-mode-tests.el
(ruby-add-log-current-method-after-inner-class-outside-methods)
(ruby-add-log-current-method-after-inner-class-outside-methods-with-text):
New tests.

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

index 17467b55549ca5a1cb4e5196d32bd4dea45931bd..4ac289d529fb81be94d0ae2b1a2ee7d64a64851f 100644 (file)
@@ -1611,7 +1611,8 @@ For example:
 See `add-log-current-defun-function'."
   (condition-case nil
       (save-excursion
-        (let* ((indent 0) mname mlist
+        (let* ((indent (ruby--add-log-current-indent))
+               mname mlist
                (start (point))
                (make-definition-re
                 (lambda (re &optional method-name?)
@@ -1626,18 +1627,30 @@ See `add-log-current-defun-function'."
                (definition-re (funcall make-definition-re ruby-defun-beg-re t))
                (module-re (funcall make-definition-re "\\(class\\|module\\)")))
           ;; Get the current method definition (or class/module).
-          (when (re-search-backward definition-re nil t)
+          (when (catch 'found
+                  (while (and (re-search-backward definition-re nil t)
+                              (if (if (string-equal "def" (match-string 1))
+                                      ;; We're inside a method.
+                                      (if (ruby-block-contains-point start)
+                                          t
+                                        ;; Try to match a method only once.
+                                        (setq definition-re module-re)
+                                        nil)
+                                    ;; Class/module. For performance,
+                                    ;; comparing indentation.
+                                    (or (not (numberp indent))
+                                        (> indent (current-indentation))))
+                                  (throw 'found t)
+                                t))))
             (goto-char (match-beginning 1))
             (if (not (string-equal "def" (match-string 1)))
                 (setq mlist (list (match-string 2)))
-              ;; We're inside the method. For classes and modules,
-              ;; this check is skipped for performance.
-              (when (ruby-block-contains-point start)
-                (setq mname (match-string 2))))
+              (setq mname (match-string 2)))
             (setq indent (current-column))
             (beginning-of-line))
           ;; Walk up the class/module nesting.
-          (while (and (> indent 0)
+          (while (and indent
+                      (> indent 0)
                       (re-search-backward module-re nil t))
             (goto-char (match-beginning 1))
             (when (< (current-column) indent)
@@ -1691,6 +1704,17 @@ See `add-log-current-defun-function'."
         (ruby-forward-sexp))
       (> (point) pt))))
 
+(defun ruby--add-log-current-indent ()
+  (save-excursion
+    (back-to-indentation)
+    (cond
+     ((looking-at "[[:graph:]]")
+      (current-indentation))
+     (ruby-use-smie
+      (smie-indent-calculate))
+     (t
+      (ruby-calculate-indent)))))
+
 (defun ruby-brace-to-do-end (orig end)
   (let (beg-marker end-marker)
     (goto-char end)
index 33fded5a59b2f2c523b2ea5f441c62ebb618ca64..e90a9e407531ac86894d86243ec62c5eacd18c5f 100644 (file)
@@ -578,6 +578,33 @@ VALUES-PLIST is a list with alternating index and value elements."
     (search-backward "_")
     (should (string= (ruby-add-log-current-method) "M::C#foo"))))
 
+(ert-deftest ruby-add-log-current-method-after-inner-class-outside-methods ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "module M
+                          |  class C
+                          |    class D
+                          |    end
+                          |
+                          |_
+                          |  end
+                          |end")
+    (search-backward "_")
+    (delete-char 1)
+    (should (string= (ruby-add-log-current-method) "M::C"))))
+
+(ert-deftest ruby-add-log-current-method-after-inner-class-outside-methods-with-text ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "module M
+                          |  class C
+                          |    class D
+                          |    end
+                          |
+                          |    FOO = 5
+                          |  end
+                          |end")
+    (search-backward "FOO")
+    (should (string= (ruby-add-log-current-method) "M::C"))))
+
 (defvar ruby-block-test-example
   (ruby-test-string
    "class C