From 1c204a8834c8e3e590fb851433d86a17bcffd9a4 Mon Sep 17 00:00:00 2001
From: Aaron Jensen <aaronjensen@gmail.com>
Date: Sat, 31 Aug 2024 19:31:20 -0400
Subject: [PATCH] Add ruby bracketed argument indentation option

* lisp/progmodes/ruby-mode.el (ruby-bracketed-args-indent),
(ruby-smie-rules): New option
* test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb:
* test/lisp/progmodes/ruby-mode-tests.el
  ("ruby-parenless-call-arguments-indent.rb"): New test case
---
 lisp/progmodes/ruby-mode.el                   | 24 ++++++++++++++
 .../ruby-bracketed-args-indent.rb             | 32 +++++++++++++++++++
 test/lisp/progmodes/ruby-mode-tests.el        |  1 +
 3 files changed, 57 insertions(+)
 create mode 100644 test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 3bcfa9ee7df..741b5167132 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -472,6 +472,26 @@ ruby-parenless-call-arguments-indent
   :safe 'booleanp
   :version "29.1")
 
+(defcustom ruby-bracketed-args-indent t
+  "Non-nil to align the contents of bracketed arguments with the brackets.
+
+Example:
+
+  qux({
+       foo => bar
+     })
+
+Set it to nil to align to the beginning of the statement:
+
+  qux({
+    foo => bar
+  })
+
+Only has effect when `ruby-use-smie' is t."
+  :type 'boolean
+  :safe 'booleanp
+  :version "31.1")
+
 (defcustom ruby-deep-arglist t
   "Deep indent lists in parenthesis when non-nil.
 Also ignores spaces after parenthesis when `space'.
@@ -826,6 +846,10 @@ ruby-smie-rules
       ))
     (`(:before . ,(or "(" "[" "{"))
      (cond
+      ((and (not (eq ruby-bracketed-args-indent t))
+            (smie-rule-prev-p "," "(" "[")
+            (smie-rule-hanging-p))
+       (cons 'column (current-indentation)))
       ((and (equal token "{")
             (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";" "do"))
             (save-excursion
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb b/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb
new file mode 100644
index 00000000000..ac7a73463bf
--- /dev/null
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb
@@ -0,0 +1,32 @@
+update({
+  key => value,
+  other_key:
+}, {
+  key => value,
+  other_key:
+})
+
+update([
+  1,
+  2
+], [
+  3,
+  4
+])
+
+update([{
+  key: "value"
+}, {
+  key: "value"
+}])
+
+update(arg1, {
+  foo: "bar"
+}, [
+  1,
+  2
+], arg2)
+
+# Local Variables:
+# ruby-bracketed-args-indent: nil
+# End:
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 2b8506a7adc..c9cde791baa 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -992,6 +992,7 @@ "ruby-block-indent.rb"
 (ruby-deftest-indent "ruby-method-call-indent.rb")
 (ruby-deftest-indent "ruby-method-params-indent.rb")
 (ruby-deftest-indent "ruby-parenless-call-arguments-indent.rb")
+(ruby-deftest-indent "ruby-bracketed-args-indent.rb")
 
 (ert-deftest ruby--test-chained-indentation ()
   (with-temp-buffer
-- 
2.42.1

