Skip to content

Commit

Permalink
Add MultilineScaladocCommentsStartOnFirstLine preference (closes #16)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdr committed Apr 7, 2011
1 parent e101a6e commit 0c917be
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Expand Up @@ -5,6 +5,7 @@
* Ability to import/export preferences as properties; --preferencesFile=<path> command-line option * Ability to import/export preferences as properties; --preferencesFile=<path> command-line option
* FIX: incorrect indent behaviour for finally block after a catch block * FIX: incorrect indent behaviour for finally block after a catch block
* Add SpacesWithinPatternBinders preference (issue #15) * Add SpacesWithinPatternBinders preference (issue #15)
* Add MultilineScaladocCommentsStartOnFirstLine preference (issue #16)


0.0.9 (26/February/11) 0.0.9 (26/February/11)


Expand Down
19 changes: 19 additions & 0 deletions README.rst
Expand Up @@ -146,6 +146,7 @@ Usage::
[+|-]formatXml Enable/disable Format XML literals [+|-]formatXml Enable/disable Format XML literals
[+|-]indentLocalDefs Enable/disable Indent local defs an extra level [+|-]indentLocalDefs Enable/disable Indent local defs an extra level
[+|-]indentPackageBlocks Enable/disable Indent package blocks [+|-]indentPackageBlocks Enable/disable Indent package blocks
[+|-]multilineScaladocCommentsStartOnFirstLine Enable/disable Start multiline Scaladoc comment body on same line as the opening '/**'
[+|-]preserveDanglingCloseParenthesis Enable/disable Allow a newline before a ')' in an argument expression. [+|-]preserveDanglingCloseParenthesis Enable/disable Allow a newline before a ')' in an argument expression.
[+|-]preserveSpaceBeforeArguments Enable/disable Preserve a space before a parenthesis argument [+|-]preserveSpaceBeforeArguments Enable/disable Preserve a space before a parenthesis argument
[+|-]rewriteArrowSymbols Enable/disable Replace arrow tokens with unicode equivalents: => with ⇒, and <- with ← [+|-]rewriteArrowSymbols Enable/disable Replace arrow tokens with unicode equivalents: => with ⇒, and <- with ←
Expand Down Expand Up @@ -357,6 +358,24 @@ Default: ``2``


The number of spaces to use for each level of indentation. The number of spaces to use for each level of indentation.


multilineScaladocCommentsStartOnFirstLine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Default: ``false``

If ``true``, start a multi-line Scaladoc comment body on same line as the opening comment delimiter::

/** This method applies f to each
* element of the given list.
*/

If ``false``, start the comment body on a separate line below the opening delimiter::

/**
* This method applies f to each
* element of the given list.
*/

preserveDanglingCloseParenthesis preserveDanglingCloseParenthesis
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Expand Down
Expand Up @@ -65,6 +65,11 @@ public class ScalariformMojo extends AbstractMojo {
*/ */
protected int indentSpaces; protected int indentSpaces;


/**
* @parameter default-value=false
*/
protected int multilineScaladocCommentsStartOnFirstLine;

/** /**
* @parameter default-value=false * @parameter default-value=false
*/ */
Expand Down Expand Up @@ -111,6 +116,7 @@ public void execute() throws MojoExecutionException {
formatXml, formatXml,
indentLocalDefs, indentLocalDefs,
indentPackageBlocks, indentPackageBlocks,
multilineScaladocCommentsStartOnFirstLine,
preserveDanglingCloseParenthesis, preserveDanglingCloseParenthesis,
preserveSpaceBeforeArguments, preserveSpaceBeforeArguments,
rewriteArrowSymbols, rewriteArrowSymbols,
Expand Down
Expand Up @@ -50,6 +50,7 @@ object MojoFormatter {
formatXml: Boolean, formatXml: Boolean,
indentLocalDefs: Boolean, indentLocalDefs: Boolean,
indentPackageBlocks: Boolean, indentPackageBlocks: Boolean,
multilineScaladocCommentsStartOnFirstLine: Boolean,
preserveDanglingCloseParenthesis: Boolean, preserveDanglingCloseParenthesis: Boolean,
preserveSpaceBeforeArguments: Boolean, preserveSpaceBeforeArguments: Boolean,
rewriteArrowSymbols: Boolean, rewriteArrowSymbols: Boolean,
Expand All @@ -68,6 +69,7 @@ object MojoFormatter {
.setPreference(FormatXml, formatXml) .setPreference(FormatXml, formatXml)
.setPreference(IndentLocalDefs, indentLocalDefs) .setPreference(IndentLocalDefs, indentLocalDefs)
.setPreference(IndentPackageBlocks, indentPackageBlocks) .setPreference(IndentPackageBlocks, indentPackageBlocks)
.setPreference(MultilineScaladocCommentsStartOnFirstLine, multilineScaladocCommentsStartOnFirstLine)
.setPreference(PreserveDanglingCloseParenthesis, preserveDanglingCloseParenthesis) .setPreference(PreserveDanglingCloseParenthesis, preserveDanglingCloseParenthesis)
.setPreference(PreserveSpaceBeforeArguments, preserveSpaceBeforeArguments) .setPreference(PreserveSpaceBeforeArguments, preserveSpaceBeforeArguments)
.setPreference(RewriteArrowSymbols, rewriteArrowSymbols) .setPreference(RewriteArrowSymbols, rewriteArrowSymbols)
Expand Down
Expand Up @@ -4,17 +4,26 @@ import scalariform.parser._
import scalariform.utils._ import scalariform.utils._
import scalariform.lexer._ import scalariform.lexer._
import scalariform.formatter.preferences._ import scalariform.formatter.preferences._
import scala.annotation.tailrec


trait CommentFormatter { self: HasFormattingPreferences with ScalaFormatter trait CommentFormatter { self: HasFormattingPreferences with ScalaFormatter


private def getLines(comment: String): (String, List[String]) = { private def getLines(comment: String): (String, List[String]) = {
val prefix = List("/** ", "/**", "/* ", "/*").find(comment.startsWith).get val prefix = List("/** ", "/**", "/* ", "/*").find(comment.startsWith).get
val (start, rest) = comment.splitAt(prefix.length) val (start, rest) = comment.splitAt(prefix.length)
val (contents, _) = rest.splitAt(rest.length - "*/".length) val (contents, _) = rest.splitAt(rest.length - "*/".length)
val lines = contents.split("""\r?\n([ \t]*\*?[ \t]?)?""", Integer.MAX_VALUE).toList val firstLine :: otherLines = contents.split("""\r?\n([ \t]*\*?)?""", Integer.MAX_VALUE).toList
(start, lines) val adjustedLines = dropInitialSpaces(firstLine, 1) :: (otherLines map { dropInitialSpaces(_, afterStarSpaces) })
(start, adjustedLines)
} }


@tailrec
private def dropInitialSpaces(s: String, maxSpacesToDrop: Int): String =
if (maxSpacesToDrop > 0 && s.startsWith(" "))
dropInitialSpaces(s drop 1, maxSpacesToDrop - 1)
else
s

private def removeTrailingWhitespace(s: String) = s.reverse.dropWhile(_.isWhitespace).reverse private def removeTrailingWhitespace(s: String) = s.reverse.dropWhile(_.isWhitespace).reverse


private def pruneEmptyInitial(lines: List[String]) = lines match { private def pruneEmptyInitial(lines: List[String]) = lines match {
Expand All @@ -24,20 +33,30 @@ trait CommentFormatter { self: HasFormattingPreferences with ScalaFormatter ⇒


private def pruneEmptyFinal(lines: List[String]) = pruneEmptyInitial(lines.reverse).reverse private def pruneEmptyFinal(lines: List[String]) = pruneEmptyInitial(lines.reverse).reverse


private def afterStarSpaces = if (formattingPreferences(MultilineScaladocCommentsStartOnFirstLine)) 2 else 1

def formatComment(comment: HiddenToken, indentLevel: Int): String = def formatComment(comment: HiddenToken, indentLevel: Int): String =
if (comment.text contains '\n') { if (comment.text contains '\n') {
val sb = new StringBuilder val sb = new StringBuilder
val (start, rawLines) = getLines(comment.text) val (start, rawLines) = getLines(comment.text)


val lines = pruneEmptyFinal(pruneEmptyInitial(rawLines)) val lines = pruneEmptyFinal(pruneEmptyInitial(rawLines))


// println("formatComment: " + (start, lines)) val startOnFirstLine = formattingPreferences(MultilineScaladocCommentsStartOnFirstLine)

sb.append(start.trim) sb.append(start.trim)
var firstLine = true
for (line lines) { for (line lines) {
val trimmedLine = removeTrailingWhitespace(line) val trimmedLine = removeTrailingWhitespace(line)
sb.append(newlineSequence).indent(indentLevel).append(" *") if (firstLine && startOnFirstLine) {
if (!trimmedLine.isEmpty) if (!trimmedLine.isEmpty)
sb.append(" ").append(trimmedLine) sb.append(" ").append(trimmedLine)
} else {
sb.append(newlineSequence).indent(indentLevel).append(" *")
if (!trimmedLine.isEmpty)
sb.append(" " * afterStarSpaces).append(trimmedLine)
}
firstLine = false
} }
sb.append(newlineSequence).indent(indentLevel).append(" */") sb.append(newlineSequence).indent(indentLevel).append(" */")
sb.toString sb.toString
Expand Down
Expand Up @@ -63,7 +63,7 @@ object AllPreferences {
val preferences: List[PreferenceDescriptor[_]] = List(RewriteArrowSymbols, IndentSpaces, SpaceBeforeColon, CompactStringConcatenation, val preferences: List[PreferenceDescriptor[_]] = List(RewriteArrowSymbols, IndentSpaces, SpaceBeforeColon, CompactStringConcatenation,
PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks, PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks,
AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, IndentLocalDefs, PreserveDanglingCloseParenthesis, AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, IndentLocalDefs, PreserveDanglingCloseParenthesis,
SpaceInsideParentheses, SpaceInsideBrackets, SpacesWithinPatternBinders) SpaceInsideParentheses, SpaceInsideBrackets, SpacesWithinPatternBinders, MultilineScaladocCommentsStartOnFirstLine)


val preferencesByKey: Map[String, PreferenceDescriptor[_]] = { val preferencesByKey: Map[String, PreferenceDescriptor[_]] = {
var map: Map[String, PreferenceDescriptor[_]] = Map() var map: Map[String, PreferenceDescriptor[_]] = Map()
Expand Down Expand Up @@ -172,3 +172,9 @@ case object SpacesWithinPatternBinders extends BooleanPreferenceDescriptor {
val description = "Add a space around the @ token in pattern binders" val description = "Add a space around the @ token in pattern binders"
val defaultValue = true val defaultValue = true
} }

case object MultilineScaladocCommentsStartOnFirstLine extends BooleanPreferenceDescriptor {
val key = "multilineScaladocCommentsStartOnFirstLine"
val description = "Start multiline Scaladoc comment body on same line as the opening '/**' "
val defaultValue = false
}
Expand Up @@ -89,4 +89,37 @@ class CommentFormatterTest extends AbstractFormatterTest {
| */ | */
|""" |"""


{
implicit val formattingPreferences = FormattingPreferences.setPreference(MultilineScaladocCommentsStartOnFirstLine, true)

"""/** This method applies f to each
| * element of the given list.
| */""" ==>
"""/** This method applies f to each
| * element of the given list.
| */
|"""

"""/** Foo
|Bar
|*Baz */""" ==>
"""/** Foo
| * Bar
| * Baz
| */
|"""

"""/** Foo
|*/""" ==>
"""/** Foo
| */
|"""

"""/**
|*/""" ==>
"""/**
| */
|"""
}

} }

0 comments on commit 0c917be

Please sign in to comment.