@@ -38,6 +38,11 @@ isPrecededByBlankLines x = case TokensOf.head (tokensOf x) of
38 Just { leadingComments } → precedingEmptyLines leadingComments > 1
38 Just { leadingComments } → precedingEmptyLines leadingComments > 1
39 Nothing → unsafeCrashWith "Unexpectedly got no tokens"
39 Nothing → unsafeCrashWith "Unexpectedly got no tokens"
41+isPrecededByNewline ∷ ∀ t. TokensOf t ⇒ t → Boolean
42+isPrecededByNewline x = case TokensOf.head (tokensOf x) of
43+ Just { leadingComments } → precedingEmptyLines leadingComments > 0
44+ Nothing → unsafeCrashWith "Unexpectedly got no tokens"
41commentIsSpaceOrLineFeed ∷ ∀ c. CST.Comment c → Boolean
46commentIsSpaceOrLineFeed ∷ ∀ c. CST.Comment c → Boolean
42commentIsSpaceOrLineFeed = case _ of
47commentIsSpaceOrLineFeed = case _ of
43 CST.Space _ → true
48 CST.Space _ → true
@@ -321,16 +326,24 @@ formatDeclarations ∷
321 Settings →
326 Settings →
322 Array (CST.Declaration Void) →
327 Array (CST.Declaration Void) →
324−formatDeclarations settings = foldMap formatOne
329+formatDeclarations settings decls =
332+ (Array.zip decls (Array.snoc (Just <$> Array.drop 1 decls) Nothing))
334+ formatWithNext (declaration /\ maybeFollowingDeclaration) = do
326− formatOne declaration = newline <> formatDeclaration settings blank declaration
335+ newline <> formatDeclaration settings blank followedByBlanks declaration
337+ followedByBlanks = case maybeFollowingDeclaration of
338+ Nothing → true -- always true so we have a final newline
339+ Just following → isPrecededByBlankLines following
328−formatDeclaration ∷ Settings → Indent → CST.Declaration Void → String
341+formatDeclaration ∷ Settings → Indent → Boolean → CST.Declaration Void → String
329−formatDeclaration settings@{ indentation } indent declaration = case declaration of
342+formatDeclaration settings@{ indentation } indent followedByBlankLines declaration = case declaration of
330 CST.DeclData dataHead maybeConstructors → do
343 CST.DeclData dataHead maybeConstructors → do
331 formatDataHead settings indent dataHead
344 formatDataHead settings indent dataHead
332 <> foldMap formatDataConstructors maybeConstructors
345 <> foldMap formatDataConstructors maybeConstructors
333− <> newline
346+ <> if followedByBlankLines then newline else blank
335 formatDataConstructors (equals /\ constructors) =
348 formatDataConstructors (equals /\ constructors) =
336 (newline <> indented)
349 (newline <> indented)
@@ -349,7 +362,7 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
349 <> formatSourceToken settings indented blank equals
362 <> formatSourceToken settings indented blank equals
351 <> formatType settings (indented <> indentation) (singleOrMultiline typo) typo
364 <> formatType settings (indented <> indentation) (singleOrMultiline typo) typo
352− <> newline
365+ <> if followedByBlankLines then newline else blank
353 CST.DeclNewtype dataHead equals name typo → do
366 CST.DeclNewtype dataHead equals name typo → do
354 formatDataHead settings indent dataHead
367 formatDataHead settings indent dataHead
355 <> (newline <> indented)
368 <> (newline <> indented)
@@ -358,7 +371,7 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
358 <> formatName settings indented blank name
371 <> formatName settings indented blank name
359 <> prefix
372 <> prefix
360 <> formatType settings indented lines typo
373 <> formatType settings indented lines typo
361− <> newline
374+ <> if followedByBlankLines then newline else blank
363 prefix = case singleOrMultilineBetween name typo of
376 prefix = case singleOrMultilineBetween name typo of
364 MultipleLines → newline <> indented
377 MultipleLines → newline <> indented
@@ -366,7 +379,7 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
366 CST.DeclClass classHead members → do
379 CST.DeclClass classHead members → do
367 formatClassHead lines settings indent classHead
380 formatClassHead lines settings indent classHead
368 <> foldMap formatMember members
381 <> foldMap formatMember members
369− <> newline
382+ <> if followedByBlankLines then newline else blank
371 formatMember (whereClause /\ labeleds) =
384 formatMember (whereClause /\ labeleds) =
372 formatSourceToken settings indent space whereClause
385 formatSourceToken settings indent space whereClause
@@ -381,13 +394,13 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
382 (formatInstance settings indent)
395 (formatInstance settings indent)
383 instances
396 instances
384− <> newline
397+ <> if followedByBlankLines then newline else blank
385 CST.DeclDerive sourceToken newtype' instanceHead →
398 CST.DeclDerive sourceToken newtype' instanceHead →
386 formatSourceToken settings indent blank sourceToken
399 formatSourceToken settings indent blank sourceToken
387 <> foldMap (formatSourceToken settings indent space) newtype'
400 <> foldMap (formatSourceToken settings indent space) newtype'
389 <> formatInstanceHead settings indent instanceHead
402 <> formatInstanceHead settings indent instanceHead
390− <> newline
403+ <> if followedByBlankLines then newline else blank
391 CST.DeclKindSignature kindOfDeclaration labeled →
404 CST.DeclKindSignature kindOfDeclaration labeled →
392 formatSourceToken settings indentation indent kindOfDeclaration
405 formatSourceToken settings indentation indent kindOfDeclaration
@@ -395,14 +408,14 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
395 CST.DeclSignature labeled → formatLabeledNameType settings indent labeled
408 CST.DeclSignature labeled → formatLabeledNameType settings indent labeled
396 CST.DeclValue valueBindingFields →
409 CST.DeclValue valueBindingFields →
397 formatValueBindingFields settings indent valueBindingFields
410 formatValueBindingFields settings indent valueBindingFields
398− <> newline
411+ <> if followedByBlankLines then newline else blank
399 CST.DeclFixity fixityFields → formatFixityFields settings indent fixityFields <> newline
412 CST.DeclFixity fixityFields → formatFixityFields settings indent fixityFields <> newline
400 CST.DeclForeign foreign'' import'' foreign''' →
413 CST.DeclForeign foreign'' import'' foreign''' →
401 formatSourceToken settings indent blank foreign''
414 formatSourceToken settings indent blank foreign''
402 <> formatSourceToken settings indent space import''
415 <> formatSourceToken settings indent space import''
404 <> formatForeign settings indent foreign'''
417 <> formatForeign settings indent foreign'''
405− <> newline
418+ <> if followedByBlankLines then newline else blank
406 CST.DeclRole type'' role'' name' roles → do
419 CST.DeclRole type'' role'' name' roles → do
407 formatSourceToken settings indentation indent type''
420 formatSourceToken settings indentation indent type''
@@ -414,7 +427,7 @@ formatDeclaration settings@{ indentation } indent declaration = case declaration
414 space <> formatRole settings indent role'
427 space <> formatRole settings indent role'
417− <> newline
430+ <> if followedByBlankLines then newline else blank
418 CST.DeclError e → absurd e
431 CST.DeclError e → absurd e
420 indented = indent <> indentation
433 indented = indent <> indentation
@@ -610,6 +623,7 @@ formatBinder settings@{ indentation } indent' binder = case binder of
610 <> foldMap
623 <> foldMap
611 (\binder' → prefix <> formatBinder settings indent' binder')
624 (\binder' → prefix <> formatBinder settings indent' binder')
613 CST.BinderNamed name' at binder' → do
627 CST.BinderNamed name' at binder' → do
614 formatName settings indent' blank name'
628 formatName settings indent' blank name'
615 <> formatSourceToken settings indent' blank at
629 <> formatSourceToken settings indent' blank at
@@ -621,6 +635,7 @@ formatBinder settings@{ indentation } indent' binder = case binder of
621 formatBinder (settings { indentation = indent' }) prefix binder1
635 formatBinder (settings { indentation = indent' }) prefix binder1
622 <> foldMap formatNamedBinder binders
636 <> foldMap formatNamedBinder binders
624 indentTrick = indent' <> indentation
639 indentTrick = indent' <> indentation
626 indent /\ prefix = case lines of
641 indent /\ prefix = case lines of
@@ -631,7 +646,8 @@ formatBinder settings@{ indentation } indent' binder = case binder of
631 formatQualifiedName settings indent' prefix name
646 formatQualifiedName settings indent' prefix name
632 <> prefix
647 <> prefix
633 <> formatBinder settings indent binder
648 <> formatBinder settings indent binder
649+ CST.BinderParens wrapped → do
634− CST.BinderParens wrapped → formatParens lines settings indent' (formatBinder settings) wrapped
650+ formatParens lines settings indent' (formatBinder settings) wrapped
635 CST.BinderRecord delimited → do
651 CST.BinderRecord delimited → do
636 formatRecord
652 formatRecord
@@ -1041,9 +1057,7 @@ formatRecordUpdate settings@{ indentation } indent' recordUpdate' = case recordU
1041 CST.RecordUpdateLeaf label' equals expr' → do
1057 CST.RecordUpdateLeaf label' equals expr' → do
1043 lines = singleOrMultiline expr'
1059 lines = singleOrMultiline expr'
1045 indentTrick = indent' <> indentation
1060 indentTrick = indent' <> indentation
1047 indent /\ prefix = case lines of
1061 indent /\ prefix = case lines of
1048 MultipleLines → indentTrick /\ (newline <> indentTrick)
1062 MultipleLines → indentTrick /\ (newline <> indentTrick)
1049 SingleLine → indent' /\ space
1063 SingleLine → indent' /\ space