1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-29 07:58:28 +00:00

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.
This commit is contained in:
Dmitry Gutov 2022-12-15 03:21:14 +02:00
parent 2ca06aed7b
commit fd403a5c5a
2 changed files with 58 additions and 7 deletions

View 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)

View 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