Subject: Re: bug#60321: 29.0.60; ruby-mode indentation of hash or array as first arg in multiline method call

From: Dmitry Gutov <[email-masked]>
Date: Mon, 2 Sep 2024 03:19:40 +0300

On 01/09/2024 22:28, Aaron Jensen wrote:

> Here's a corrected patch for that particular example. Thank you for 
> finding that. I think I missed it because as long as you type the code 
> in, it indents fine. I still have a lot to understand about SMIE, so if 
> anything looks off in my patch, please let me know.

Thanks! Just being thorough. We can add this example to the args-indent 
test file, too.

Here's a bonus example which looks off but would be more difficult to 
fix (and it's not urgent, given the expression is in mixed styles):

foo([{
   a: 2
},
      {
        b: 3
      },
      4
     ])

It would be nice to at least handle the last arg correctly - maybe we'll 
just get that supported in the ts mode at some later date.

> I didn't change the default. I wasn't sure if you wanted to change the 
> defaults of all of the variables you added in the last round or just 
> this one, so I'll let you handle that the way you want to.

Sure. I think we can add this into Emacs 30 too, while the change is off 
by default.

A few other things:

* I think the docstring should say "Set it to nil to align to the line 
with the open bracket" - it doesn't necessarily align to the beginning 
of the statement (seems like a good thing).

* Let's change the first example to this, for less ambiguity?

   foo
     .update({
       key => value,
       other_key:
     }, {
       key => value,
       other_key:
     })

* Support for the new option in ruby-ts-mode (it's good to have parity). 
Could you take the attached patch for a spin? Seems to work here, but 
I'd like to have an extra confirmation.

diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index 5f4e11e0b4c..adcdf15c7ad 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -842,6 +842,16 @@ ruby-ts--parent-call-or-bol
      ;; No paren/curly/brace found on the same line.
      ((< (treesit-node-start found) parent-bol)
       parent-bol)
+     ;; Nesting of brackets args.
+     ((and
+       (not (eq ruby-bracketed-args-indent t))
+       (string-match-p "\\`array\\|hash\\'" (treesit-node-type parent))
+       (equal (treesit-node-parent parent) found)
+       ;; Grandparent is not a parenless call.
+       (or (not (equal (treesit-node-type found) "argument_list"))
+           (equal (treesit-node-type (treesit-node-child found 0))
+                  "(")))
+      parent-bol)
      ;; Hash or array opener on the same line.
      ((string-match-p "\\`array\\|hash\\'" (treesit-node-type found))
       (save-excursion
diff --git a/test/lisp/progmodes/ruby-ts-mode-tests.el b/test/lisp/progmodes/ruby-ts-mode-tests.el
index 61ef80eb610..05d98974acf 100644
--- a/test/lisp/progmodes/ruby-ts-mode-tests.el
+++ b/test/lisp/progmodes/ruby-ts-mode-tests.el
@@ -326,6 +326,7 @@ "ruby-block-indent.rb"
 (ruby-ts-deftest-indent "ruby-method-call-indent.rb")
 (ruby-ts-deftest-indent "ruby-method-params-indent.rb")
 (ruby-ts-deftest-indent "ruby-parenless-call-arguments-indent.rb")
+(ruby-ts-deftest-indent "ruby-bracketed-args-indent.rb")
 
 (provide 'ruby-ts-mode-tests)