Skip to content

Commit

Permalink
Merge pull request #1 from jackcviers/scala3-indent-cycle
Browse files Browse the repository at this point in the history
WIP: Adding cycling indent *NOT READY FOR MERGE*
  • Loading branch information
Kazark authored May 18, 2022
2 parents 1ef3ce5 + 74eaa24 commit 35f265f
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
82 changes: 80 additions & 2 deletions scala-mode-indent.el
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ Scaladoc behavior of indenting comment lines to the second asterisk."
:safe #'booleanp
:group 'scala)

(defcustom scala-indent:use-cycle-indent nil
"When non-nil, indentation will cycle from the new indent
strategy indent, the last known indent, and the left margin on
subsequent indent-line calls."
:type 'boolean
:safe #'booleanp
:group 'scala)

(defun scala-indent:run-on-strategy ()
"Returns the currently effecti run-on strategy"
(or scala-indent:effective-run-on-strategy
Expand Down Expand Up @@ -897,8 +905,66 @@ strings"
(beginning-of-line)
(when (looking-at "^\\s +$") (point)))))

(defun scala-indent:indent-line (&optional strategy)
"Indents the current line."
(defvar-local scala-indent:cycle-indent-stack (list)
"The automatically buffer local scala indent cycle stack.
The stack is initialized as (left-margin, (current-indentation))
when the custom var \"scala-indent:use-cycle-indent\" is non-nil
and \"scala-indent:indent-line\" is called. Subsequent
\"scala-indent:indent-line\" calls pop the indentation value from
the stack, until it is empty, resetting the indentation cycle.")



(defun scala-indent:cycle-indent-stack-push (indentation)
"Pushes an integer value onto the \"scala-indent:cycle-indent-stack\".
Will fail if INDENTATION is not an integer"

(if (integerp indentation)
(add-to-list 'scala-indent:cycle-indent-stack indentation)
(error "\"scala-indent:cycle-indent-stack-push\": Invalid INDENTATION argument %s"
indentation)))

(defun scala-indent:cycle-indent-stack-pop ()
"Gets the top value of the \"scala-indent:cycle-indent-stack\" stack.
Modifies the stack in-place."

(pop (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))))

(defun scala-indent:cycle-indent-stack-depth ()
"The current depth of the \"scala-indent:cycle-indent-stack\" stack"

(length (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))))


(defun scala-indent:cycle-indent-stack-emptyp (x)
"Check if the \"scala-indent:cycle-indent-stack\" is empty.
Returns t if the \"scala-indent:cycle-indent-stack\" is empty,
nil otherwise."

(= (length (buffer-local-value 'scala-indent:cycle-indent-stack (current-buffer))) 0))

(defun scala-indent:cycle-indent-line (&optional strategy)
"Cycle scala indentation using optionally passed STRATEGY.
When the \"scala-indent:cycle-indent-stack\" is empty, push 0 and
the current indentation onto the stack, then indent according to
the optionally passed STRATEGY. Indent to the top of
\"scala-indent:cycle-indent-stack\" when non-empty."

(interactive "*")
(cond ((scala-indent:cycle-indent-stack-emptyp nil)
(scala-indent:cycle-indent-stack-push (current-indentation))
(scala-indent:cycle-indent-stack-push 0)
(call-interactively 'scala-indent:strategy-indent-line t))
(t (scala-indent:indent-line-to (scala-indent:cycle-indent-stack-pop)))))

;; the previously-named scala-indent:indent-line
(defun scala-indent:strategy-indent-line (&optional strategy)
"Indent lines according to the OPTIONAL scala indentation STRATEGY."
(interactive "*")
(let ((state (save-excursion (syntax-ppss (line-beginning-position)))))
(if (nth 8 state) ;; 8 = start pos of comment or string
Expand All @@ -918,6 +984,18 @@ strings"
(scala-indent:indent-code-line strategy)))
)

(defun scala-indent:indent-line (&optional strategy)
"Indent the current line with cycling.
If the custom var \"scala-indent:use-cycle-indent\" is non-nil,
cycle-indent using the optionally passed STRATEGY. Indent using
the optionally passed STRATEGY without cycling otherwise."

(interactive "*")
(if scala-indent:use-cycle-indent
(call-interactively t 'scala-indent:cycle-indent-line)
(call-interactively t 'scala-indent:strategy-indent-line)))

(defun scala-indent:indent-with-reluctant-strategy ()
(interactive "*")
(scala-indent:indent-line scala-indent:reluctant-strategy))
Expand Down
26 changes: 26 additions & 0 deletions test/scala-mode-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,29 @@ comment. A concrete example may be viewed at https://github.com/scala/scala/blob
"/* &*/"
"110111"
"DDDOOO"))

(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-1 ()
"Custom \"scala-indent:use-cycle-indent\" should be nil by default."

(should-not scala-indent:use-cycle-indent ))

(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-2 ()
"Custom \"scala-indent:use-cycle-indent\" must be a boolean."

:expected-result :failed
(custom-set-variables '(scala-indent:use-cycle-indent "gobbledygook"))
(should (= 'scala-indent:use-cycle-indent "gobbledygook")))

(ert-deftest scala-indent:scala-indent:use-cycle-indent-test-3 ()
"Custom \"scala-indent:use-cycle-indent\" should be settable to a boolean value."

(custom-set-variables '(scala-indent:use-cycle-indent t))
(should 'scala-indent:use-cycle-indent )
(custom-set-variables '(scala-indent:use-cycle-indent nil)))

(ert-deftest scala-indent:scala-indent:cycle-indent-stack-test-1 ()
"\"scala-indent:cycle-indent-stack\" should be 0 current-indentation after one call."
(custom-set-variables '(scala-indent:use-cycle-indent t))
(call-interactively (scala-indent:indent-line))
(should (buffer-local-value 'scala-indent:cycle-indent-stack))
(custom-set-variables '(scala-indent:use-cycle-indent nil)))

0 comments on commit 35f265f

Please sign in to comment.