unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dgutov@yandex.ru>
To: Aaron Jensen <aaronjensen@gmail.com>
Cc: 60186@debbugs.gnu.org
Subject: bug#60186: 29.0.60; ruby-mode indentation of multi-line expressions
Date: Thu, 22 Dec 2022 23:21:15 +0200	[thread overview]
Message-ID: <60e207e0-7378-ad9f-3ef0-99df1c139939@yandex.ru> (raw)
In-Reply-To: <CAHyO48wapPi=D7C9WZCBx8-iCPmqO9sNWLC0v_M8BpVr89LN3g@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]

On 22/12/2022 04:31, Aaron Jensen wrote:
> On Wed, Dec 21, 2022 at 5:48 PM Dmitry Gutov <dgutov@yandex.ru> wrote:
>> See this new patch instead.
>>
>> The code is messier than I'd like it to be, but it seems to handle all
>> of the cases mentioned so far and more (including the
>> dots-at-indentation style, thanks).
> 
> Looks good, for the things I mentioned. I found one more case:
> 
> x.foo do
>    foo
> end.bar do
>      bar
>    end
> 
> Should be:
> 
> x.foo do
>    foo
> end.bar do
>    bar
> end

Hm, this one breaks the approach I used with the last patch (which was 
to count lines from the beginning of the statement).

Let's see if blocks can just be aligned to the indentation of its 
opener's line.

> I can't vouch for writing in this style, but it should only get one
> indentation increase in this instance, rather than, I believe.
> 
> Interestingly enough, I found a bug with enh-ruby-mode that ruby-mode
> now indents correctly:
> 
> x =
>    bar(
>      y
>    ).map do |i|
>    i
>    end

Cool. It seems I broke it for the default indent algo, however. ;-( In 
the previous patch.

See the new one attached.

BTW, I'm surprised you haven't mentioned the case of parenless calls:

foo bar,
     baz,
     tee

IUUC the Rails core has decided to forgo this indentation style. Not 
sure about the statistics across other popular projects.

[-- Attachment #2: ruby-simplified-indent-v4.diff --]
[-- Type: text/x-patch, Size: 6710 bytes --]

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 1f3e9b6ae7b..542c8ac02f1 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -285,6 +285,11 @@ ruby-method-params-indent
   :safe (lambda (val) (or (memq val '(t nil)) (numberp val)))
   :version "29.1")
 
+(defcustom ruby-indent-simplified nil
+  "Foo bar."
+  :type 'boolean
+  :safe 'booleanp)
+
 (defcustom ruby-deep-arglist t
   "Deep indent lists in parenthesis when non-nil.
 Also ignores spaces after parenthesis when `space'.
@@ -416,6 +421,7 @@ ruby-smie-grammar
      '((right "=")
        (right "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^="
               "<<=" ">>=" "&&=" "||=")
+       (right "?")
        (nonassoc ".." "...")
        (left "&&" "||")
        (nonassoc "<=>")
@@ -608,10 +614,10 @@ ruby-smie--backward-token
           "def=")
          (t tok)))))))
 
-(defun ruby-smie--indent-to-stmt ()
+(defun ruby-smie--indent-to-stmt (&optional offset)
   (save-excursion
     (smie-backward-sexp ";")
-    (cons 'column (smie-indent-virtual))))
+    (cons 'column (+ (smie-indent-virtual) (or offset 0)))))
 
 (defun ruby-smie--indent-to-stmt-p (keyword)
   (or (eq t ruby-align-to-stmt-keywords)
@@ -642,7 +648,9 @@ ruby-smie-rules
               (forward-comment -1)
               (not (eq (preceding-char) ?:))))
        ;; Curly block opener.
-       (ruby-smie--indent-to-stmt))
+       (if ruby-indent-simplified
+           (cons 'column (current-indentation))
+         (ruby-smie--indent-to-stmt)))
       ((smie-rule-hanging-p)
        ;; Treat purely syntactic block-constructs as being part of their parent,
        ;; when the opening token is hanging and the parent is not an
@@ -683,7 +691,10 @@ ruby-smie-rules
            (skip-chars-forward " \t")
            (cons 'column (current-column)))
        (smie-rule-parent (or ruby-method-params-indent 0))))
-    ('(:before . "do") (ruby-smie--indent-to-stmt))
+    ('(:before . "do")
+     (if ruby-indent-simplified
+         (cons 'column (current-indentation))
+       (ruby-smie--indent-to-stmt)))
     ('(:before . ".")
      (if (smie-rule-sibling-p)
          (when ruby-align-chained-calls
@@ -696,8 +707,10 @@ ruby-smie-rules
                    (not (smie-rule-bolp)))))
            (cons 'column (current-column)))
        (smie-backward-sexp ".")
-       (cons 'column (+ (current-column)
-                        ruby-indent-level))))
+       (if ruby-indent-simplified
+           (ruby-smie--indent-to-stmt ruby-indent-level)
+         (cons 'column (+ (current-column)
+                          ruby-indent-level)))))
     (`(:before . ,(or "else" "then" "elsif" "rescue" "ensure"))
      (smie-rule-parent))
     (`(:before . ,(or "when" "in"))
@@ -710,14 +723,16 @@ ruby-smie-rules
                      "<<=" ">>=" "&&=" "||=" "and" "or"))
      (and (smie-rule-parent-p ";" nil)
           (smie-indent--hanging-p)
-          ruby-indent-level))
+          (if ruby-indent-simplified
+              (ruby-smie--indent-to-stmt ruby-indent-level)
+            ruby-indent-level)))
     (`(:before . "=")
      (save-excursion
       (and (smie-rule-parent-p " @ ")
            (goto-char (nth 1 (smie-indent--parent)))
            (smie-rule-prev-p "def=")
            (cons 'column (+ (current-column) ruby-indent-level -3)))))
-    (`(:after . ,(or "?" ":")) ruby-indent-level)
+    (`(:after . ,(or "?" ":")) (unless ruby-indent-simplified ruby-indent-level))
     (`(:before . ,(guard (memq (intern-soft token) ruby-alignable-keywords)))
      (when (not (ruby--at-indentation-p))
        (if (ruby-smie--indent-to-stmt-p token)
@@ -725,7 +740,17 @@ ruby-smie-rules
          (cons 'column (current-column)))))
     ('(:before . "iuwu-mod")
      (smie-rule-parent ruby-indent-level))
-    ))
+    (`(:before . ,_)
+     (when (and ruby-indent-simplified
+                (not (or (member token '(","))
+                         (smie-rule-prev-p ";"))))
+       (let* ((stmt-beg (save-excursion
+                          (smie-backward-sexp ";")
+                          (point)))
+              (nls (1- (count-lines stmt-beg (point)))))
+         (when (smie-indent--hanging-p)
+           (cl-incf nls))
+         (ruby-smie--indent-to-stmt (if (> nls 0) ruby-indent-level 0)))))))
 
 (defun ruby--at-indentation-p (&optional point)
   (save-excursion
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby-indent-simplified.rb b/test/lisp/progmodes/ruby-mode-resources/ruby-indent-simplified.rb
new file mode 100644
index 00000000000..9f1fb0edd80
--- /dev/null
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby-indent-simplified.rb
@@ -0,0 +1,62 @@
+4 +
+  5 +
+  6 +
+  7
+
+foo = obj.bar { |m| tee(m) } +
+  obj.qux { |m| hum(m) }
+
+foo.
+  bar
+  .baz
+
+qux = foo.fee ?
+  bar :
+  tee
+
+foo2 =
+  subject.
+  update(
+    2
+  )
+
+m1 = foo
+  .asdasd
+  .proc do |**args|
+    p(**args)
+  end
+
+m2 = foo
+  .asdasd
+  .proc { |**args|
+    p(**args)
+  }
+
+bar.foo do
+  bar
+end
+
+bar.foo(tee) do
+  bar
+end
+
+bar.foo(tee) {
+  bar
+}
+
+# Endless methods.
+class Bar
+  def foo(abc) = bar +
+    baz
+end
+
+x.foo do
+  foo
+end.bar do
+  bar
+end
+
+# Local Variables:
+# ruby-method-params-indent: t
+# ruby-indent-simplified: t
+# End:
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
index 6a69d9db78a..d0ee8f8f52b 100644
--- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
@@ -226,6 +226,7 @@ def begin
 
 foo.
   bar
+  .baz
 
 # https://github.com/rails/rails/blob/17f5d8e062909f1fcae25351834d8e89967b645e/activesupport/lib/active_support/time_with_zone.rb#L206
 foo # comment intended to confuse the tokenizer
@@ -380,6 +381,18 @@ def bar
   i + 1
 end
 
+m1 = foo
+       .asdasd
+       .proc do |**args|
+  p(**args)
+end
+
+m2 = foo
+       .asdasd
+       .proc { |**args|
+  p(**args)
+}
+
 bar.foo do
   bar
 end
@@ -398,6 +411,12 @@ def bar
   end
 end
 
+x.foo do
+  foo
+end.bar do
+  bar
+end
+
 foo |
   bar
 
@@ -541,4 +560,5 @@ def baz.full_name = "#{bar} 3"
 
 # Local Variables:
 # ruby-method-params-indent: t
+# ruby-indent-simplified: nil
 # End:
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 560f780285a..4a86492b137 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -957,6 +957,7 @@ ruby-deftest-indent
 
 (ruby-deftest-indent "ruby.rb")
 (ruby-deftest-indent "ruby-method-params-indent.rb")
+(ruby-deftest-indent "ruby-indent-simplified.rb")
 
 (ert-deftest ruby--test-chained-indentation ()
   (with-temp-buffer

  reply	other threads:[~2022-12-22 21:21 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-19  2:54 bug#60186: 29.0.60; ruby-mode indentation of multi-line expressions Aaron Jensen
2022-12-20  2:12 ` Dmitry Gutov
2022-12-20  2:17   ` Dmitry Gutov
2022-12-20  4:48   ` Aaron Jensen
2022-12-20  5:56     ` Aaron Jensen
2022-12-20 15:53       ` Dmitry Gutov
2022-12-20 16:19     ` Dmitry Gutov
2022-12-20 17:31       ` Dmitry Gutov
2022-12-21  1:34         ` Aaron Jensen
2022-12-20 20:05       ` Aaron Jensen
2022-12-21 22:48         ` Dmitry Gutov
2022-12-22  2:31           ` Aaron Jensen
2022-12-22 21:21             ` Dmitry Gutov [this message]
2022-12-23  4:12               ` Aaron Jensen
2022-12-23 22:26                 ` Dmitry Gutov
2022-12-24  0:17                   ` Aaron Jensen
2022-12-24 22:47                     ` Dmitry Gutov
2022-12-25  0:12                       ` Aaron Jensen
2022-12-25 21:23                         ` Dmitry Gutov
2022-12-25 21:29                         ` bug#60321: 29.0.60; ruby-mode indentation of hash or array as first arg in multiline method call Dmitry Gutov
2022-12-25 23:46                           ` Aaron Jensen
2022-12-27  1:16                             ` Dmitry Gutov
2022-12-27  1:38                               ` Aaron Jensen
2022-12-25  0:14                       ` bug#60186: 29.0.60; ruby-mode indentation of multi-line expressions Aaron Jensen
2022-12-25 21:29                         ` Dmitry Gutov
2022-12-27  1:28                         ` Dmitry Gutov
2022-12-27  1:47                           ` Aaron Jensen
2022-12-27 15:56                             ` Dmitry Gutov
2022-12-27 16:34                               ` Aaron Jensen
2022-12-27 23:04                                 ` Dmitry Gutov
2022-12-28  0:38                                   ` Aaron Jensen
2022-12-28  1:02                                     ` Dmitry Gutov
2022-12-28  3:47                                       ` Aaron Jensen
2022-12-28 12:47                                         ` Dmitry Gutov
2022-12-28 21:24                                           ` Dmitry Gutov
2022-12-29 22:59                                             ` Aaron Jensen
2022-12-30 15:02                                               ` Dmitry Gutov
2022-12-30 18:00                                                 ` Aaron Jensen
2022-12-30 18:16                                                   ` Aaron Jensen
2022-12-30 22:07                                                     ` Dmitry Gutov
2022-12-31  1:11                                                       ` Aaron Jensen
2023-01-22  3:02                                                         ` Dmitry Gutov
2023-01-22  5:15                                                           ` Aaron Jensen

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=60e207e0-7378-ad9f-3ef0-99df1c139939@yandex.ru \
    --to=dgutov@yandex.ru \
    --cc=60186@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).