From fef7cffd021f26d6881872c20a18191c3c2968d1 Mon Sep 17 00:00:00 2001
From: Ming Zhao <ming.zhao@databricks.com>
Date: Tue, 26 Oct 2021 04:36:45 +0000
Subject: [PATCH] Introduce `scala-indent:defition-parameter-scaling-factor`
 config to control whether the parameter list of function/class should have a
 different indentation level.

See discussion in #172
---
 scala-mode-indent.el | 11 +++++++++++
 scala-mode-syntax.el | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/scala-mode-indent.el b/scala-mode-indent.el
index 486ae65..69f6fcf 100644
--- a/scala-mode-indent.el
+++ b/scala-mode-indent.el
@@ -16,6 +16,14 @@ indentation will be one or two steps depending on context."
   :safe #'integerp
   :group 'scala)
 
+(defcustom scala-indent:defition-parameter-scaling-factor 1
+  "Scale the number of spaces used to indent the parameter list
+of class/function definitions. See also
+https://github.com/hvesalai/emacs-scala-mode/issues/172"
+  :type 'integer
+  :safe #'integerp
+  :group 'scala)
+
 (defcustom scala-indent:indent-value-expression nil
   "Whether or not to indent multi-line value expressions, with
 one extra step. When true, indenting will be
@@ -629,6 +637,9 @@ anchor for calculating block indent for current point (or point
              (> (line-number-at-pos) (line-number-at-pos anchor))
              (> start (match-beginning 0))))
       (+ (* 2 scala-indent:step) lead))
+     ;; optionally double the step for parameter list
+     ((scala-syntax:in-definition-parameter-list anchor start)
+      (+ (* scala-indent:defition-parameter-scaling-factor scala-indent:step) lead))
      ;; normal block line
      (t  (+ scala-indent:step lead)))))
 
diff --git a/scala-mode-syntax.el b/scala-mode-syntax.el
index edab1ab..6801d48 100644
--- a/scala-mode-syntax.el
+++ b/scala-mode-syntax.el
@@ -1018,6 +1018,25 @@ val a, b = (1, 2)
   (scala-syntax:find-brace-equals-or-next)
   (scala-syntax:handle-brace-equals-or-next))
 
+(defun scala-syntax:in-definition-parameter-list (anchor start)
+  "Return t if the (anchor, start) region is the parameter list
+of a definition(class, def, etc.)"
+  (save-excursion
+    (goto-char anchor)
+    (when
+	(or (string= "class" (current-word))
+	    (string= "def" (current-word)))
+      ;; try to find (
+      (while (and (< (point) start)
+		  (/= (char-after) ?\())
+	(forward-char))
+      (when (< (point) start)
+	;; And we haven't see ) yet.
+	(while (and (< (point) start)
+		    (/= (char-after) ?\)))
+	  (forward-char))
+	(= (point) start)))))
+
 (defun scala-syntax:find-brace-equals-or-next ()
   (scala-syntax:go-to-pos
    (save-excursion