From: Dmitry Gutov <dgutov@yandex.ru>
To: Aaron Jensen <aaronjensen@gmail.com>
Cc: 54702@debbugs.gnu.org
Subject: bug#54702: 29.0.50; ruby-mode indentation: endless methods
Date: Fri, 16 Dec 2022 02:33:17 +0200 [thread overview]
Message-ID: <0178ae56-21d9-55e9-68f6-b2e8e2a483ff@yandex.ru> (raw)
In-Reply-To: <CAHyO48zdubRfw-U_823=GJaaU5K-b-A4mbwP8CT=ScFb20xw3A@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2146 bytes --]
Hi Aaron,
Sorry for the long pause. You said you're using something else, though,
so it didn't seem urgent (and I've yet to encounter endless methods at
$day_job, FWIW).
On 28/04/2022 02:58, Aaron Jensen wrote:
> On Tue, Apr 26, 2022 at 10:44 PM Dmitry Gutov <dgutov@yandex.ru> wrote:
>> Thanks for the report.
>>
>> I'll work on this further, but here's a quick-and-dirty patch to fix the
>> indentation problems.
>
> Great, thank you. I've since moved back to enh-ruby-mode and I was
> able to patch it to support this (though that project appears to be
> currently not accepting contributions).
Not a problem for me, but could you test the attached patch anyway?
It seems to handle a bunch of different/complex cases fine without
regressions, but it's always better with a second pair of eyes.
> I'd probably use ruby-mode if
> it supported indenting long parameter/argument lists the way the
> non-smie version does, like this:
>
> def some_method(
> some_param,
> some_other_param
> )
Now that the SMIE stuff is again in my short-term memory, it shouldn't
be too hard. Just please file a separate bug report (slash feature
request) with a precise example. Bonus points for linking to a relevant
Rubocop rule, so that we can pick a better name for the new user option.
I don't see the non-SMIE version indenting it like this -- it looks more
like this instead (and only if I set ruby-deep-indent-paren to nil):
def test2 (
asd,
asd
asd
)
So let's start with a couple of good examples.
> I believe I've seen you imply concerns about enh-ruby-mode -- do you
> have any aside from the fact that it's not in core and it requires a
> ruby process? It's mostly worked well for me, but I don't know what I
> don't know.
My main problem with it is the spotty maintenance like in this example:
https://github.com/zenspider/enhanced-ruby-mode/issues/96
But it might work fine for many people. Especially those who don't use Robe.
Some previous versions of it (probably by the previous maintainer) were
really broken, so I just took up ruby-mode instead. I haven't tried
using its latest versions much.
[-- Attachment #2: ruby-endless-methods.diff --]
[-- Type: text/x-patch, Size: 4796 bytes --]
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 4ac289d529..4d4ca635a4 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -134,6 +134,12 @@ ruby-symbol-chars
(defconst ruby-symbol-re (concat "[" ruby-symbol-chars "]")
"Regexp to match symbols.")
+(defconst ruby-endless-method-head-re
+ (format " *%s+[?!]? *\\(([^()]*)\\)? *=" ruby-symbol-re)
+ "Regexp to match the beginning of an endless method definition.
+
+It should match the part after \"def\" and until \"=\".")
+
(defvar ruby-use-smie t)
(make-obsolete-variable 'ruby-use-smie nil "28.1")
@@ -351,7 +357,8 @@ ruby-smie-grammar
(exp (exp1) (exp "," exp) (exp "=" exp)
(id " @ " exp))
(exp1 (exp2) (exp2 "?" exp1 ":" exp1))
- (exp2 (exp3) (exp3 "." exp3))
+ (exp2 (exp3) (exp3 "." exp3)
+ (exp3 "def=" exp3))
(exp3 ("def" insts "end")
("begin" insts-rescue-insts "end")
("do" insts "end")
@@ -528,6 +535,9 @@ ruby-smie--forward-token
(ruby-smie--forward-token)) ;Fully redundant.
(t ";")))
((equal tok "&.") ".")
+ ((and (equal tok "def")
+ (looking-at ruby-endless-method-head-re))
+ "def=")
(t tok)))))))))
(defun ruby-smie--backward-token ()
@@ -575,6 +585,9 @@ ruby-smie--backward-token
(ruby-smie--backward-token)) ;Fully redundant.
(t ";")))
((equal tok "&.") ".")
+ ((and (equal tok "def")
+ (looking-at (concat "def" ruby-endless-method-head-re)))
+ "def=")
(t tok)))))))
(defun ruby-smie--indent-to-stmt ()
@@ -641,9 +654,11 @@ ruby-smie-rules
(unless (or (eolp) (forward-comment 1))
(cons 'column (current-column)))))
('(:before . " @ ")
- (save-excursion
- (skip-chars-forward " \t")
- (cons 'column (current-column))))
+ (if (smie-rule-parent-p "def=")
+ (smie-rule-parent)
+ (save-excursion
+ (skip-chars-forward " \t")
+ (cons 'column (current-column)))))
('(:before . "do") (ruby-smie--indent-to-stmt))
('(:before . ".")
(if (smie-rule-sibling-p)
@@ -672,6 +687,9 @@ ruby-smie-rules
(and (smie-rule-parent-p ";" nil)
(smie-indent--hanging-p)
ruby-indent-level))
+ (`(:before . "=")
+ (and (smie-rule-parent-p " @ ")
+ (smie-rule-parent ruby-indent-level)))
(`(:after . ,(or "?" ":")) ruby-indent-level)
(`(:before . ,(guard (memq (intern-soft token) ruby-alignable-keywords)))
(when (not (ruby--at-indentation-p))
@@ -1631,7 +1649,7 @@ ruby-add-log-current-method
(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)
+ (if (ruby-block-contains-point (1- start))
t
;; Try to match a method only once.
(setq definition-re module-re)
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
index f39489071e..cbeb362ef0 100644
--- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
@@ -500,3 +500,26 @@ def resolve(**args)
member.call(**args)
end
+
+# Endless methods.
+class Bar
+ def foo(abc) =
+ bar +
+ bar
+ .baz
+
+ def bar =
+ 123 +
+ 4
+
+ def request_params = {
+ headers: request_headers,
+ body: request_body
+ }
+end
+
+
+class Foo
+ def foo(...) = z
+ def bar = y
+end
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index e90a9e4075..9be01dc78f 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -605,6 +605,18 @@ ruby-add-log-current-method-after-inner-class-outside-methods-with-text
(search-backward "FOO")
(should (string= (ruby-add-log-current-method) "M::C"))))
+(ert-deftest ruby-add-log-current-method-after-endless-method ()
+ (ruby-with-temp-buffer (ruby-test-string
+ "module M
+ | class C
+ | def foo =
+ | 4_
+ | end
+ |end")
+ (search-backward "_")
+ (delete-char 1)
+ (should (string= (ruby-add-log-current-method) "M::C#foo"))))
+
(defvar ruby-block-test-example
(ruby-test-string
"class C
next prev parent reply other threads:[~2022-12-16 0:33 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-04 2:03 bug#54702: 29.0.50; ruby-mode indentation: endless methods Aaron Jensen
2022-04-27 2:44 ` Dmitry Gutov
2022-04-27 23:58 ` Aaron Jensen
2022-12-16 0:33 ` Dmitry Gutov [this message]
2022-12-16 5:07 ` Aaron Jensen
2022-12-16 12:31 ` Dmitry Gutov
2022-12-16 12:40 ` Dmitry Gutov
2022-12-16 14:49 ` Eli Zaretskii
2022-12-18 12:06 ` Dmitry Gutov
2022-12-18 15:42 ` Aaron Jensen
2022-12-16 13:12 ` Aaron Jensen
2022-12-16 16:15 ` Dmitry Gutov
2022-12-16 16:24 ` Aaron Jensen
2022-12-16 17:49 ` Dmitry Gutov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0178ae56-21d9-55e9-68f6-b2e8e2a483ff@yandex.ru \
--to=dgutov@yandex.ru \
--cc=54702@debbugs.gnu.org \
--cc=aaronjensen@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).