Skip to content

Commit 35f265f

Browse files
authored
Merge pull request #1 from jackcviers/scala3-indent-cycle
WIP: Adding cycling indent *NOT READY FOR MERGE*
2 parents 1ef3ce5 + 74eaa24 commit 35f265f

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

scala-mode-indent.el

+80-2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ Scaladoc behavior of indenting comment lines to the second asterisk."
133133
:safe #'booleanp
134134
:group 'scala)
135135

136+
(defcustom scala-indent:use-cycle-indent nil
137+
"When non-nil, indentation will cycle from the new indent
138+
strategy indent, the last known indent, and the left margin on
139+
subsequent indent-line calls."
140+
:type 'boolean
141+
:safe #'booleanp
142+
:group 'scala)
143+
136144
(defun scala-indent:run-on-strategy ()
137145
"Returns the currently effecti run-on strategy"
138146
(or scala-indent:effective-run-on-strategy
@@ -897,8 +905,66 @@ strings"
897905
(beginning-of-line)
898906
(when (looking-at "^\\s +$") (point)))))
899907

900-
(defun scala-indent:indent-line (&optional strategy)
901-
"Indents the current line."
908+
(defvar-local scala-indent:cycle-indent-stack (list)
909+
"The automatically buffer local scala indent cycle stack.
910+
911+
The stack is initialized as (left-margin, (current-indentation))
912+
when the custom var \"scala-indent:use-cycle-indent\" is non-nil
913+
and \"scala-indent:indent-line\" is called. Subsequent
914+
\"scala-indent:indent-line\" calls pop the indentation value from
915+
the stack, until it is empty, resetting the indentation cycle.")
916+
917+
918+
919+
(defun scala-indent:cycle-indent-stack-push (indentation)
920+
"Pushes an integer value onto the \"scala-indent:cycle-indent-stack\".
921+
922+
Will fail if INDENTATION is not an integer"
923+
924+
(if (integerp indentation)
925+
(add-to-list 'scala-indent:cycle-indent-stack indentation)
926+
(error "\"scala-indent:cycle-indent-stack-push\": Invalid INDENTATION argument %s"
927+
indentation)))
928+
929+
(defun scala-indent:cycle-indent-stack-pop ()
930+
"Gets the top value of the \"scala-indent:cycle-indent-stack\" stack.
931+
932+
Modifies the stack in-place."
933+
934+
(pop (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))))
935+
936+
(defun scala-indent:cycle-indent-stack-depth ()
937+
"The current depth of the \"scala-indent:cycle-indent-stack\" stack"
938+
939+
(length (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))))
940+
941+
942+
(defun scala-indent:cycle-indent-stack-emptyp (x)
943+
"Check if the \"scala-indent:cycle-indent-stack\" is empty.
944+
945+
Returns t if the \"scala-indent:cycle-indent-stack\" is empty,
946+
nil otherwise."
947+
948+
(= (length (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))) 0))
949+
950+
(defun scala-indent:cycle-indent-line (&optional strategy)
951+
"Cycle scala indentation using optionally passed STRATEGY.
952+
953+
When the \"scala-indent:cycle-indent-stack\" is empty, push 0 and
954+
the current indentation onto the stack, then indent according to
955+
the optionally passed STRATEGY. Indent to the top of
956+
\"scala-indent:cycle-indent-stack\" when non-empty."
957+
958+
(interactive "*")
959+
(cond ((scala-indent:cycle-indent-stack-emptyp nil)
960+
(scala-indent:cycle-indent-stack-push (current-indentation))
961+
(scala-indent:cycle-indent-stack-push 0)
962+
(call-interactively 'scala-indent:strategy-indent-line t))
963+
(t (scala-indent:indent-line-to (scala-indent:cycle-indent-stack-pop)))))
964+
965+
;; the previously-named scala-indent:indent-line
966+
(defun scala-indent:strategy-indent-line (&optional strategy)
967+
"Indent lines according to the OPTIONAL scala indentation STRATEGY."
902968
(interactive "*")
903969
(let ((state (save-excursion (syntax-ppss (line-beginning-position)))))
904970
(if (nth 8 state) ;; 8 = start pos of comment or string
@@ -918,6 +984,18 @@ strings"
918984
(scala-indent:indent-code-line strategy)))
919985
)
920986

987+
(defun scala-indent:indent-line (&optional strategy)
988+
"Indent the current line with cycling.
989+
990+
If the custom var \"scala-indent:use-cycle-indent\" is non-nil,
991+
cycle-indent using the optionally passed STRATEGY. Indent using
992+
the optionally passed STRATEGY without cycling otherwise."
993+
994+
(interactive "*")
995+
(if scala-indent:use-cycle-indent
996+
(call-interactively t 'scala-indent:cycle-indent-line)
997+
(call-interactively t 'scala-indent:strategy-indent-line)))
998+
921999
(defun scala-indent:indent-with-reluctant-strategy ()
9221000
(interactive "*")
9231001
(scala-indent:indent-line scala-indent:reluctant-strategy))

test/scala-mode-test.el

+26
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,29 @@ comment. A concrete example may be viewed at https://github.com/scala/scala/blob
176176
"/* &*/"
177177
"110111"
178178
"DDDOOO"))
179+
180+
(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-1 ()
181+
"Custom \"scala-indent:use-cycle-indent\" should be nil by default."
182+
183+
(should-not scala-indent:use-cycle-indent ))
184+
185+
(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-2 ()
186+
"Custom \"scala-indent:use-cycle-indent\" must be a boolean."
187+
188+
:expected-result :failed
189+
(custom-set-variables '(scala-indent:use-cycle-indent "gobbledygook"))
190+
(should (= 'scala-indent:use-cycle-indent "gobbledygook")))
191+
192+
(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-3 ()
193+
"Custom \"scala-indent:use-cycle-indent\" should be settable to a boolean value."
194+
195+
(custom-set-variables '(scala-indent:use-cycle-indent t))
196+
(should 'scala-indent:use-cycle-indent )
197+
(custom-set-variables '(scala-indent:use-cycle-indent nil)))
198+
199+
(ert-deftest scala-indent:scala-indent:cycle-indent-stack-test-1 ()
200+
"\"scala-indent:cycle-indent-stack\" should be 0 current-indentation after one call."
201+
(custom-set-variables '(scala-indent:use-cycle-indent t))
202+
(call-interactively (scala-indent:indent-line))
203+
(should (buffer-local-value 'scala-indent:cycle-indent-stack))
204+
(custom-set-variables '(scala-indent:use-cycle-indent nil)))

0 commit comments

Comments
 (0)