diff --git a/pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt b/pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt index 43127fcd..40aeba12 100644 --- a/pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt +++ b/pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt @@ -872,11 +872,14 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe } private fun formatIf(node: Node): FormatNode { + val separator = if (node.isMultiline()) forceLine() else spaceOrLine() val nodes = formatGeneric(node.children) { _, next -> - if (next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR) { - Space - } else spaceOrLine() + // produce `else if` in the case of nested if. + // note: don't need to handle if `next.children[0]` is an affix because that can't be + // emitted as `else if` anyway. + if (next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR) Space + else separator } return Group(newId(), nodes) } @@ -968,10 +971,11 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe } private fun formatLetExpr(node: Node): FormatNode { + val separator = if (node.isMultiline()) forceLine() else spaceOrLine() val nodes = formatGenericWithGen( node.children, - { _, next -> if (next.type == NodeType.LET_PARAMETER_DEFINITION) Space else spaceOrLine() }, + { _, next -> if (next.type == NodeType.LET_PARAMETER_DEFINITION) Space else separator }, ) { node, next -> if (next == null) { if (node.type == NodeType.LET_EXPR) { @@ -1323,7 +1327,7 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe } private fun hasTrailingAffix(node: Node, next: Node): Boolean { - if (node.span.lineEnd < next.span.lineBegin) return false + if (node.isMultiline()) return false var n: Node? = next while (n != null) { if (n.type.isAffix && node.span.lineEnd == n.span.lineBegin) return true @@ -1450,6 +1454,8 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe // returns true if this node is not an affix or terminal private fun Node.isProper(): Boolean = !type.isAffix && type != NodeType.TERMINAL + private fun Node.isMultiline(): Boolean = span.lineBegin < span.lineEnd + private inline fun List.splitOn(pred: (T) -> Boolean): Pair, List> { val index = indexOfFirst { pred(it) } return if (index == -1) { diff --git a/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl b/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl index 5263672e..01a5b744 100644 --- a/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl +++ b/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl @@ -5,3 +5,29 @@ foo = else if (someAnotherCondition) 30000 else 4 + +foo2 = if (bar) 1 else 2 + +// respect newlines in if/else if they exist. +// if anything of these wrap, everything wraps. +foo3 = + if (bar) + 1 else 2 + +foo4 = + if (bar) 1 else + 2 + +foo5 = + if (bar) 1 + else 2 + +foo6 = + if (bar) + 1 + else + 2 + +foo7 = + if /* some comment */ (bar) 1 + else 2 diff --git a/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl b/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl index 474c869c..b4bc4b2b 100644 --- a/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl +++ b/pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl @@ -15,3 +15,11 @@ qux = let ( // some comment bar = 5 ) bar + +quzzy = + let (baz = 1) baz + 1 + +// respect newlines in lets +quzzzy = + let (baz = 1) + baz + 1 diff --git a/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl b/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl index 18bbbf10..be360158 100644 --- a/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl +++ b/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl @@ -7,3 +7,37 @@ foo = 30000 else 4 + +foo2 = if (bar) 1 else 2 + +// respect newlines in if/else if they exist. +// if anything of these wrap, everything wraps. +foo3 = + if (bar) + 1 + else + 2 + +foo4 = + if (bar) + 1 + else + 2 + +foo5 = + if (bar) + 1 + else + 2 + +foo6 = + if (bar) + 1 + else + 2 + +foo7 = + if /* some comment */ (bar) + 1 + else + 2 diff --git a/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl b/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl index 496477a9..cbd48798 100644 --- a/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl +++ b/pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl @@ -25,3 +25,10 @@ qux = bar = 5 ) bar + +quzzy = let (baz = 1) baz + 1 + +// respect newlines in lets +quzzzy = + let (baz = 1) + baz + 1