Permalink
Browse files

Add IndentLocalDefs preference to indent local methods an extra level

  • Loading branch information...
mdr committed Jan 21, 2011
1 parent dc58f10 commit 13b6ec2424a10194c558f0aa938984a7982800c5
View
@@ -4,6 +4,7 @@
* Add Maven formatter plugin (contributed by Adam Crain -- https://github.com/jadamcrain)
* FIX: Bug with lexing """ at end of text
* Add AlignSingleLineCaseStatements preferences to align the arrows of consecutive single-line case statements
+* Add IndentLocalDefs preference to indent local methods an extra level
0.0.7 (18/October/10)
View
@@ -132,6 +132,7 @@ Usage::
[+|-]compactStringConcatenation Enable/disable Omit spaces when formatting a '+' operator on String literals
[+|-]doubleIndentClassDeclaration Enable/disable Double indent either a class's parameters or its inheritance list
[+|-]formatXml Enable/disable Format XML literals
+ [+|-]indentLocalDefs Enable/disable Indent local defs an extra level
[+|-]indentPackageBlocks Enable/disable Indent package blocks
[+|-]preserveSpaceBeforeArguments Enable/disable Preserve a space before a parenthesis argument
[+|-]rewriteArrowSymbols Enable/disable Replace arrow tokens with unicode equivalents: => with ⇒, and <- with ←
@@ -294,6 +295,24 @@ Default: ``true``
Format embedded XML literals; if ``false`` they will be left untouched.
+indentLocalDefs
+~~~~~~~~~~~~~~~
+
+Default: ``false``
+
+If ``true``, indent local methods an extra level, with the intention of distinguishing them from other statements. For example,::
+
+ class A {
+ def find(...) = {
+ val x = ...
+ def find0() = {
+ ...
+ }
+ find0(...)
+ }
+ }
+
+
indentPackageBlocks
~~~~~~~~~~~~~~~~~~~
View
@@ -132,6 +132,7 @@ Usage::
[+|-]compactStringConcatenation Enable/disable Omit spaces when formatting a '+' operator on String literals
[+|-]doubleIndentClassDeclaration Enable/disable Double indent either a class's parameters or its inheritance list
[+|-]formatXml Enable/disable Format XML literals
+ [+|-]indentLocalDefs Enable/disable Indent local defs an extra level
[+|-]indentPackageBlocks Enable/disable Indent package blocks
[+|-]preserveSpaceBeforeArguments Enable/disable Preserve a space before a parenthesis argument
[+|-]rewriteArrowSymbols Enable/disable Replace arrow tokens with unicode equivalents: => with ⇒, and <- with ←
@@ -294,6 +295,24 @@ Default: ``true``
Format embedded XML literals; if ``false`` they will be left untouched.
+indentLocalDefs
+~~~~~~~~~~~~~~~
+
+Default: ``false``
+
+If ``true``, indent local methods an extra level, with the intention of distinguishing them from other statements. For example,::
+
+ class A {
+ def find(...) = {
+ val x = ...
+ def find0() = {
+ ...
+ }
+ find0(...)
+ }
+ }
+
+
indentPackageBlocks
~~~~~~~~~~~~~~~~~~~
@@ -5,7 +5,7 @@ class Project(info: ProjectInfo) extends ParentProject(info) {
trait FormatterOptions /* extends ScalariformPlugin */ {
- /* override */ def scalariformOptions = Seq(VerboseScalariform, RewriteArrowSymbols(true), AlignParameters(true) /* AlignSingleLineCaseStatements(true) */)
+ /* override */ def scalariformOptions = Seq(VerboseScalariform, RewriteArrowSymbols(true), AlignParameters(true) /* AlignSingleLineCaseStatements(true) */ )
}
@@ -454,7 +454,9 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi
formatResult ++= format(caseClauses)(newFormatterState)
case Right(statSeq)
- if (!singleLineBlock) {
+ if (singleLineBlock)
+ formatResult ++= format(statSeq)(newFormatterState)
+ else {
if (statSeq.firstTokenOption.isDefined) {
statSeq.firstStatOpt match {
case Some(Expr(List(anonFn@AnonymousFunction(params, arrowToken, body))))
@@ -468,49 +470,56 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi
case Some((selfReference, arrow)) if !hiddenPredecessors(selfReference.firstToken).containsNewline
CompactEnsuringGap
case _
- indentedInstruction
+ statFormatterState(statSeq.firstStatOpt)(indentedState).currentIndentLevelInstruction
}
formatResult = formatResult.before(statSeq.firstToken, instruction)
formatResult ++= format(statSeq)(indentedState)
}
}
formatResult = formatResult.before(rbrace, newFormatterState.currentIndentLevelInstruction)
- } else
- formatResult ++= format(statSeq)(newFormatterState)
+ }
}
formatResult
}
+ private def statFormatterState(statOpt: Option[Stat])(implicit formatterState: FormatterState) = condOpt(statOpt) {
+ case Some(FullDefOrDcl(_, _, FunDefOrDcl(_, _, _, _, _, _, true))) if formattingPreferences(IndentLocalDefs) formatterState.indent
+ } getOrElse formatterState
+
def format(statSeq: StatSeq)(implicit formatterState: FormatterState): FormatResult = {
val StatSeq(selfReferenceOpt: Option[(Expr, Token)], firstStatOpt: Option[Stat], otherStats: List[(Token, Option[Stat])]) = statSeq
var formatResult: FormatResult = NoFormatResult
+ val firstStatFormatterState = statFormatterState(firstStatOpt)
+
for ((selfReference, arrow) selfReferenceOpt) {
formatResult ++= format(selfReference)
for (stat firstStatOpt if hiddenPredecessors(stat.firstToken).containsNewline)
- formatResult = formatResult.before(stat.firstToken, formatterState.currentIndentLevelInstruction)
+ formatResult = formatResult.before(stat.firstToken, firstStatFormatterState.currentIndentLevelInstruction)
}
- for (stat firstStatOpt) {
- formatResult ++= format(stat)
- }
+ for (stat firstStatOpt)
+ formatResult ++= format(stat)(firstStatFormatterState)
for ((semi, otherStatOption) otherStats) {
+ val otherStatFormatterState = statFormatterState(otherStatOption)
+
if (isInferredNewline(semi))
- formatResult = formatResult.formatNewline(semi, formatterState.currentIndentLevelInstruction)
+ formatResult = formatResult.formatNewline(semi, otherStatFormatterState.currentIndentLevelInstruction)
for (otherStat otherStatOption) {
if (!isInferredNewline(semi)) {
val firstToken = otherStat.firstToken
- val instruction = if (hiddenPredecessors(firstToken).containsNewline)
- formatterState.currentIndentLevelInstruction
- else
- CompactEnsuringGap
+ val instruction =
+ if (hiddenPredecessors(firstToken).containsNewline)
+ otherStatFormatterState.currentIndentLevelInstruction
+ else
+ CompactEnsuringGap
formatResult = formatResult.before(firstToken, instruction)
}
- formatResult ++= format(otherStat)
+ formatResult ++= format(otherStat)(otherStatFormatterState)
}
}
@@ -605,7 +614,7 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi
// TODO: Lots
var formatResult: FormatResult = NoFormatResult
val FunDefOrDcl(defToken: Token, nameToken: Token, typeParamClauseOpt: Option[TypeParamClause], paramClauses: ParamClauses,
- returnTypeOpt: Option[(Token, Type)], funBodyOpt: Option[FunBody]) = funDefOrDcl
+ returnTypeOpt: Option[(Token, Type)], funBodyOpt: Option[FunBody], localDef: Boolean) = funDefOrDcl
for (typeParamClause typeParamClauseOpt)
formatResult ++= format(typeParamClause.contents)
formatResult ++= formatParamClauses(paramClauses)
@@ -56,7 +56,7 @@ abstract trait BooleanPreferenceDescriptor extends PreferenceDescriptor[Boolean]
object AllPreferences {
val preferences: List[PreferenceDescriptor[_]] = List(RewriteArrowSymbols, IndentSpaces, SpaceBeforeColon, CompactStringConcatenation,
PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks,
- AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent)
+ AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, IndentLocalDefs)
val preferencesByKey: Map[String, PreferenceDescriptor[_]] = {
var map: Map[String, PreferenceDescriptor[_]] = Map()
@@ -136,3 +136,8 @@ case object AlignSingleLineCaseStatements extends BooleanPreferenceDescriptor {
}
+case object IndentLocalDefs extends BooleanPreferenceDescriptor {
+ val key = "indentLocalDefs"
+ val description = "Indent local defs an extra level"
+ val defaultValue = false
+}
@@ -238,7 +238,8 @@ case class FunDefOrDcl(defToken: Token,
typeParamClauseOpt: Option[TypeParamClause],
paramClauses: ParamClauses,
returnTypeOpt: Option[(Token, Type)],
- funBodyOpt: Option[FunBody]) extends DefOrDcl {
+ funBodyOpt: Option[FunBody],
+ localDef: Boolean) extends DefOrDcl {
lazy val tokens = flatten(defToken, nameToken, typeParamClauseOpt, paramClauses, returnTypeOpt, funBodyOpt)
@@ -1187,11 +1187,11 @@ class ScalaParser(tokens: Array[Token]) {
}
}
- private def defOrDcl(): DefOrDcl = {
+ private def defOrDcl(localDef: Boolean = false): DefOrDcl = {
currentTokenType match {
case VAL patDefOrDcl()
case VAR patDefOrDcl()
- case DEF funDefOrDcl()
+ case DEF funDefOrDcl(localDef)
case TYPE typeDefOrDcl()
case _ tmplDef()
}
@@ -1229,7 +1229,7 @@ class ScalaParser(tokens: Array[Token]) {
PatDefOrDcl(valOrVarToken, pattern_, otherPatterns.toList, typedOpt_, equalsClauseOption)
}
- private def funDefOrDcl(): FunDefOrDcl = {
+ private def funDefOrDcl(localDef: Boolean): FunDefOrDcl = {
val defToken = accept(DEF)
if (THIS) {
val thisToken = nextToken()
@@ -1243,7 +1243,7 @@ class ScalaParser(tokens: Array[Token]) {
val constrExpr_ = constrExpr()
ExprFunBody(equalsToken, constrExpr_)
}
- FunDefOrDcl(defToken, thisToken, None, paramClauses_, None, Some(funBody))
+ FunDefOrDcl(defToken, thisToken, None, paramClauses_, None, Some(funBody), localDef)
} else {
val nameToken = ident()
val typeParamClauseOpt_ = typeParamClauseOpt(allowVariance = false)
@@ -1259,7 +1259,7 @@ class ScalaParser(tokens: Array[Token]) {
val (equalsToken, expr_) = equalsExpr()
Some(ExprFunBody(equalsToken, expr_))
}
- FunDefOrDcl(defToken, nameToken, typeParamClauseOpt_, paramClauses_, returnTypeOpt, funBodyOpt)
+ FunDefOrDcl(defToken, nameToken, typeParamClauseOpt_, paramClauses_, returnTypeOpt, funBodyOpt, localDef)
}
}
@@ -1544,7 +1544,7 @@ class ScalaParser(tokens: Array[Token]) {
val localModifiers_ = localModifiers()
// val modifierCondition = true // TODO: !!!!
- val defOrDcl_ = or(defOrDcl(), tmplDef())
+ val defOrDcl_ = or(defOrDcl(localDef = true), tmplDef())
FullDefOrDcl(annotations_, localModifiers_, defOrDcl_)
}
@@ -2,6 +2,7 @@ package scalariform.formatter
import scalariform.parser._
import scalariform.formatter._
+import scalariform.formatter.preferences._
// format: OFF
class DefOrDclFormatterTest extends AbstractFormatterTest {
@@ -102,6 +103,40 @@ class DefOrDclFormatterTest extends AbstractFormatterTest {
|sealed trait B""" ==>
"""private[a] sealed trait B"""
+ {
+
+ implicit val formattingPreferences =
+ FormattingPreferences
+ .setPreference(IndentLocalDefs, true)
+
+ """class A {
+ | def b() = {
+ | def c() = 42
+ | println("d")
+ | def e() =
+ | 42
+ |println("f")
+ | def g() {
+ |println("h")
+ |}
+ | c() * e()
+ | }
+ |}""" ==>
+ """class A {
+ | def b() = {
+ | def c() = 42
+ | println("d")
+ | def e() =
+ | 42
+ | println("f")
+ | def g() {
+ | println("h")
+ | }
+ | c() * e()
+ | }
+ |}"""
+ }
+
def parse(parser: ScalaParser) = parser.nonLocalDefOrDcl()
type Result = FullDefOrDcl

0 comments on commit 13b6ec2

Please sign in to comment.