Subject: bug#60186: 29.0.60; ruby-mode indentation of multi-line expressions

From: Dmitry Gutov <[email-masked]>
Date: Tue, 20 Dec 2022 19:31:31 +0200

On 20/12/2022 18:19, Dmitry Gutov wrote:
> Okay, so there should be two basic cases:
> 
> - Indent to the beginning of the statement,
> - If there was a line continuation (no matter how many), indent 1 extra 
> level?

Here's another quick attempt to make this work without rewriting the 
rest of the logic.

Cases 1 and 2 seem to work now, but not the block example.

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 1f3e9b6ae7b..02d2e0a2a75 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 t
+  "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'.
@@ -608,15 +613,20 @@ 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)
       (memq (intern keyword) ruby-align-to-stmt-keywords)))
 
+(defconst ruby-smie--operators '("=" "+" "-" "*" "/" "&&" "||" "%" "**" "^" "&"
+                                 "<=>" ">" "<" ">=" "<=" "==" "===" "!=" "<<" ">>"
+                                 "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^=" "|"
+                                 "<<=" ">>=" "&&=" "||=" "and" "or"))
+
 (defun ruby-smie-rules (kind token)
   (pcase (cons kind token)
     ('(:elem . basic) ruby-indent-level)
@@ -684,6 +694,14 @@ ruby-smie-rules
            (cons 'column (current-column)))
        (smie-rule-parent (or ruby-method-params-indent 0))))
     ('(:before . "do") (ruby-smie--indent-to-stmt))
+    (`(:after . ,(pred (lambda (token)
+                         (and ruby-indent-simplified
+                              (or
+                               (equal token ".")
+                               (member token ruby-smie--operators))))))
+     (if (smie-indent--hanging-p)
+         (ruby-smie--indent-to-stmt ruby-indent-level)
+       (ruby-smie--indent-to-stmt)))
     ('(:before . ".")
      (if (smie-rule-sibling-p)
          (when ruby-align-chained-calls
@@ -695,9 +713,11 @@ ruby-smie-rules
                    (goto-char (nth 1 parent))
                    (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)
+         (smie-backward-sexp ".")
+         (cons 'column (+ (current-column)
+                          ruby-indent-level)))))
     (`(:before . ,(or "else" "then" "elsif" "rescue" "ensure"))
      (smie-rule-parent))
     (`(:before . ,(or "when" "in"))