summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Gutov <dgutov@yandex.ru>2022-12-15 03:21:14 +0200
committerDmitry Gutov <dgutov@yandex.ru>2022-12-15 03:21:44 +0200
commitfd403a5c5a87adb8cf42f82c9c0cea4e029767d6 (patch)
treecfcb75c5f9a49b84a2f561252673b7ed1ab4a8e5
parent2ca06aed7b39afdc00041ab7cd9c7a8cb50332f6 (diff)
downloademacs-fd403a5c5a87adb8cf42f82c9c0cea4e029767d6.tar.gz
Fix ruby-add-log-current-method after nested class definition
* 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.
-rw-r--r--lisp/progmodes/ruby-mode.el38
-rw-r--r--test/lisp/progmodes/ruby-mode-tests.el27
2 files changed, 58 insertions, 7 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 17467b55549..4ac289d529f 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -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)
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 33fded5a59b..e90a9e40753 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -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