Subject: bug#23015: 25.0.92; ruby-mode misindents arguments of a method call inside continuation

From: Dmitry Gutov <[email-masked]>
Date: Tue, 15 Mar 2016 02:27:05 +0200

It indents

foo =
  subject.update(
  a: 1
)

whereas it should be

foo =
  subject.update(
    a: 1
  )

Patch attached.

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 1c9f0f4..35d0cc4 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -629,19 +629,13 @@ ruby-smie-rules
         ;; because when `.' is inside the line, the
         ;; additional indentation from it looks out of place.
         ((smie-rule-parent-p ".")
-         (let (smie--parent)
-           (save-excursion
-             ;; Traverse up the parents until the parent is "." at
-             ;; indentation, or any other token.
-             (while (and (let ((parent (smie-indent--parent)))
-                           (goto-char (cadr parent))
-                           (save-excursion
-                             (unless (integerp (car parent)) (forward-char -1))
-                             (not (ruby-smie--bosp))))
-                         (progn
-                           (setq smie--parent nil)
-                           (smie-rule-parent-p "."))))
-             (smie-rule-parent))))
+         ;; Traverse up the call chain until the parent is not `.',
+         ;; or `.' at indentation, or at eol.
+         (while (and (not (ruby-smie--bosp))
+                     (equal (nth 2 (smie-backward-sexp ".")) ".")
+                     (not (ruby-smie--bosp)))
+           (forward-char -1))
+         (smie-indent-virtual))
         (t (smie-rule-parent))))))
     (`(:after . ,(or `"(" "[" "{"))
      ;; FIXME: Shouldn't this be the default behavior of
diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb
index 6ab814a..6793bfd 100644
--- a/test/indent/ruby.rb
+++ b/test/indent/ruby.rb
@@ -405,6 +405,17 @@ zoo
 a.records().map(&:b).zip(
   foo)
 
+foo1 =
+  subject.update(
+    1
+  )
+
+foo2 =
+  subject.
+    update(
+      2
+    )
+
 # FIXME: This is not consistent with the example below it, but this
 # offset only happens if the colon is at eol, which wouldn't be often.
 # Tokenizing `bar:' as `:bar =>' would be better, but it's hard to