branch: elpa/scala-mode commit b55ca8334014202c452c17af232bbcc96ed96ce1 Merge: 95e3742 2f7b335 Author: Heikki Vesalainen <heikkivesalai...@yahoo.com> Commit: Heikki Vesalainen <heikkivesalai...@yahoo.com>
Merge pull request #23 from hvesalai/issue22 indent `while` like `if`, `for` et al (fixes #22) Also fixes indenting of bar in the following example if (foo) (1, 2) else (2, 3) bar --- README.md | 15 +++++++++++++++ scala-mode-indent.el | 27 ++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d6ae63a..863a7e8 100644 --- a/README.md +++ b/README.md @@ -318,6 +318,21 @@ customization variable *frame-background-mode* to *dark* (use **M-x** - highlights only properly formatted string and character constants - indenting a code line removes trailing whitespace +## Known issues + +*do/while* is not always handled correctly. For example: + +```scala +do + foo +while (bar) + foo +``` + +The indenter thinks the second occurrence of `foo` is the body of the while. +To work around this, terminate the while with a semicolon, +or put a blank line after it. + ## Future work - syntax-begin-function for reliably fontifying elements which span diff --git a/scala-mode-indent.el b/scala-mode-indent.el index cb5d6e4..0c95410 100644 --- a/scala-mode-indent.el +++ b/scala-mode-indent.el @@ -505,23 +505,36 @@ point or nil if the point is not in a enumerator element > 1." ;;; Body ;;; -(defconst scala-indent:value-keyword-re - (regexp-opt '("if" "else" "yield" "for" "try" "finally" "catch") 'words)) +(defconst scala-indent:control-keywords-cond-re + (regexp-opt '("if" "while" "for") 'words) + "All the flow control keywords that are followed by a +condition (or generators in the case of 'for') in parentheses.") + +(defconst scala-indent:control-keywords-other-re + (regexp-opt '("else" "do" "yield" "try" "finally" "catch") 'words) + "Other flow control keywords (not followed by parentheses)") + +(defconst scala-indent:control-keywords-re + (concat scala-indent:control-keywords-cond-re + scala-indent:control-keywords-other-re)) (defun scala-indent:body-p (&optional point) - "Returns the position of '=', 'if or 'else if' (TODO: or '=>') -symbol if current point (or point 'point) is on a line that -follows said symbol, or nil if not." + "Returns the position of '=' symbol, or one of the +scala-indent:control-keywords-re or +scala-indent:control-keywords-cond-re keywords if current +point (or point 'point) is on a line that follows said symbol or +keyword, or nil if not." (save-excursion (when point (goto-char point)) (scala-syntax:beginning-of-code-line) (or (scala-syntax:looking-back-token scala-syntax:body-start-re 3) + (scala-syntax:looking-back-token scala-indent:control-keywords-other-re) (progn ;; if, else if (when (scala-syntax:looking-back-token ")" 1) (goto-char (match-end 0)) (backward-list)) - (when (scala-syntax:looking-back-token scala-indent:value-keyword-re) + (when (scala-syntax:looking-back-token scala-indent:control-keywords-cond-re) (goto-char (match-beginning 0)) (when (and (looking-at "\\<if\\>") (scala-syntax:looking-back-token "\\<else\\>")) @@ -534,7 +547,7 @@ follows said symbol, or nil if not." (let ((declaration-end (scala-indent:body-p point))) (when declaration-end (goto-char declaration-end) - (if (looking-at scala-indent:value-keyword-re) + (if (looking-at scala-indent:control-keywords-re) (point) (when (scala-indent:backward-sexp-to-beginning-of-line) (scala-indent:goto-run-on-anchor