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