From c1969b27da36c59fd1cc7e8793109bac6f6dd8a5 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Sun, 26 Jan 2020 03:16:19 +0100 Subject: [PATCH 1/6] A different approach to avoiding trailing whitespace --- prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index d76dd121..236bb114 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1967,7 +1967,11 @@ layoutWadlerLeijen Empty -> best nl cc ds Char c -> let !cc' = cc+1 in SChar c (best nl cc' ds) Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds) - Line -> SLine i (best i i ds) + Line -> let x = best i i ds + i' = case x of + SLine{} -> 0 + _ -> i + in SLine i' x FlatAlt x _ -> best nl cc (Cons i x ds) Cat x y -> best nl cc (Cons i x (Cons i y ds)) Nest j x -> let !ij = i+j in best nl cc (Cons ij x ds) From 3374b8c911e9d11dc507d471cfdb3b35f4d3835b Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Mon, 27 Jan 2020 14:35:58 +0100 Subject: [PATCH 2/6] Also avoid add trailing whitespace at the end of the document --- prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index 236bb114..875f44e1 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1969,6 +1969,7 @@ layoutWadlerLeijen Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds) Line -> let x = best i i ds i' = case x of + SEmpty -> 0 SLine{} -> 0 _ -> i in SLine i' x From 5b866745c7582c39785a684d70322158a77b0355 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Mon, 15 Jun 2020 01:27:04 +0200 Subject: [PATCH 3/6] Add comment --- prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index 875f44e1..a0b6c2c3 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1968,6 +1968,9 @@ layoutWadlerLeijen Char c -> let !cc' = cc+1 in SChar c (best nl cc' ds) Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds) Line -> let x = best i i ds + -- Don't produce indentation if there's no + -- following text on the same line. + -- This prevents trailing whitespace. i' = case x of SEmpty -> 0 SLine{} -> 0 From 5f63588ed3a67696a44a4bb1127e70685f0633c3 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Mon, 15 Jun 2020 15:35:48 +0200 Subject: [PATCH 4/6] Try keeping track of the annotation level within `best` --- .../src/Data/Text/Prettyprint/Doc/Internal.hs | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index a0b6c2c3..f95ebc6b 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1950,7 +1950,7 @@ layoutWadlerLeijen (FittingPredicate fits) pageWidth_ doc - = best 0 0 (Cons 0 doc Nil) + = best 0 0 0 (Cons 0 doc Nil) where -- * current column >= current nesting level @@ -1958,34 +1958,38 @@ layoutWadlerLeijen best :: Int -- Current nesting level -> Int -- Current column, i.e. "where the cursor is" + -> Int -- Current annotation nesting level -> LayoutPipeline ann -- Documents remaining to be handled (in order) -> SimpleDocStream ann - best !_ !_ Nil = SEmpty - best nl cc (UndoAnn ds) = SAnnPop (best nl cc ds) - best nl cc (Cons i d ds) = case d of + best !_ !_ !_ Nil = SEmpty + best nl cc an (UndoAnn ds) = SAnnPop (best nl cc (an-1) ds) + best nl cc an (Cons i d ds) = case d of Fail -> SFail - Empty -> best nl cc ds - Char c -> let !cc' = cc+1 in SChar c (best nl cc' ds) - Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds) - Line -> let x = best i i ds + Empty -> best nl cc an ds + Char c -> let !cc' = cc+1 in SChar c (best nl cc' an ds) + Text l t -> let !cc' = cc+l in SText l t (best nl cc' an ds) + Line -> let x = best i i an ds -- Don't produce indentation if there's no -- following text on the same line. -- This prevents trailing whitespace. - i' = case x of - SEmpty -> 0 - SLine{} -> 0 - _ -> i + i' = + if an > 0 + then i + else case x of + SEmpty -> 0 + SLine{} -> 0 + _ -> i in SLine i' x - FlatAlt x _ -> best nl cc (Cons i x ds) - Cat x y -> best nl cc (Cons i x (Cons i y ds)) - Nest j x -> let !ij = i+j in best nl cc (Cons ij x ds) - Union x y -> let x' = best nl cc (Cons i x ds) - y' = best nl cc (Cons i y ds) + FlatAlt x _ -> best nl cc an (Cons i x ds) + Cat x y -> best nl cc an (Cons i x (Cons i y ds)) + Nest j x -> let !ij = i+j in best nl cc an (Cons ij x ds) + Union x y -> let x' = best nl cc an (Cons i x ds) + y' = best nl cc an (Cons i y ds) in selectNicer nl cc x' y' - Column f -> best nl cc (Cons i (f cc) ds) - WithPageWidth f -> best nl cc (Cons i (f pageWidth_) ds) - Nesting f -> best nl cc (Cons i (f i) ds) - Annotated ann x -> SAnnPush ann (best nl cc (Cons i x (UndoAnn ds))) + Column f -> best nl cc an (Cons i (f cc) ds) + WithPageWidth f -> best nl cc an (Cons i (f pageWidth_) ds) + Nesting f -> best nl cc an (Cons i (f i) ds) + Annotated ann x -> SAnnPush ann (best nl cc (an+1) (Cons i x (UndoAnn ds))) -- Select the better fitting of two documents: -- Choice A if it fits, otherwise choice B. From 7f24d8c771b97e668d3d65857ee3e36167b6e3e7 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Wed, 17 Jun 2020 17:20:49 +0200 Subject: [PATCH 5/6] Revert "Try keeping track of the annotation level within `best`" This reverts commit 025007255f6e1cbd1270c643dbc768e004e56e83. --- .../src/Data/Text/Prettyprint/Doc/Internal.hs | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index f95ebc6b..a0b6c2c3 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1950,7 +1950,7 @@ layoutWadlerLeijen (FittingPredicate fits) pageWidth_ doc - = best 0 0 0 (Cons 0 doc Nil) + = best 0 0 (Cons 0 doc Nil) where -- * current column >= current nesting level @@ -1958,38 +1958,34 @@ layoutWadlerLeijen best :: Int -- Current nesting level -> Int -- Current column, i.e. "where the cursor is" - -> Int -- Current annotation nesting level -> LayoutPipeline ann -- Documents remaining to be handled (in order) -> SimpleDocStream ann - best !_ !_ !_ Nil = SEmpty - best nl cc an (UndoAnn ds) = SAnnPop (best nl cc (an-1) ds) - best nl cc an (Cons i d ds) = case d of + best !_ !_ Nil = SEmpty + best nl cc (UndoAnn ds) = SAnnPop (best nl cc ds) + best nl cc (Cons i d ds) = case d of Fail -> SFail - Empty -> best nl cc an ds - Char c -> let !cc' = cc+1 in SChar c (best nl cc' an ds) - Text l t -> let !cc' = cc+l in SText l t (best nl cc' an ds) - Line -> let x = best i i an ds + Empty -> best nl cc ds + Char c -> let !cc' = cc+1 in SChar c (best nl cc' ds) + Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds) + Line -> let x = best i i ds -- Don't produce indentation if there's no -- following text on the same line. -- This prevents trailing whitespace. - i' = - if an > 0 - then i - else case x of - SEmpty -> 0 - SLine{} -> 0 - _ -> i + i' = case x of + SEmpty -> 0 + SLine{} -> 0 + _ -> i in SLine i' x - FlatAlt x _ -> best nl cc an (Cons i x ds) - Cat x y -> best nl cc an (Cons i x (Cons i y ds)) - Nest j x -> let !ij = i+j in best nl cc an (Cons ij x ds) - Union x y -> let x' = best nl cc an (Cons i x ds) - y' = best nl cc an (Cons i y ds) + FlatAlt x _ -> best nl cc (Cons i x ds) + Cat x y -> best nl cc (Cons i x (Cons i y ds)) + Nest j x -> let !ij = i+j in best nl cc (Cons ij x ds) + Union x y -> let x' = best nl cc (Cons i x ds) + y' = best nl cc (Cons i y ds) in selectNicer nl cc x' y' - Column f -> best nl cc an (Cons i (f cc) ds) - WithPageWidth f -> best nl cc an (Cons i (f pageWidth_) ds) - Nesting f -> best nl cc an (Cons i (f i) ds) - Annotated ann x -> SAnnPush ann (best nl cc (an+1) (Cons i x (UndoAnn ds))) + Column f -> best nl cc (Cons i (f cc) ds) + WithPageWidth f -> best nl cc (Cons i (f pageWidth_) ds) + Nesting f -> best nl cc (Cons i (f i) ds) + Annotated ann x -> SAnnPush ann (best nl cc (Cons i x (UndoAnn ds))) -- Select the better fitting of two documents: -- Choice A if it fits, otherwise choice B. From 9073e369fcaea65669b9a0b594a6658523bb420a Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Tue, 30 Jun 2020 02:57:55 +0200 Subject: [PATCH 6/6] Add testcase --- prettyprinter/test/Testsuite/Main.hs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/prettyprinter/test/Testsuite/Main.hs b/prettyprinter/test/Testsuite/Main.hs index b59c6b66..95b18c64 100644 --- a/prettyprinter/test/Testsuite/Main.hs +++ b/prettyprinter/test/Testsuite/Main.hs @@ -89,6 +89,8 @@ tests = testGroup "Tests" , testCase "Line within align" regressionUnboundedGroupedLineWithinAlign ] ] + , testCase "Indentation on otherwise empty lines results in trailing whitespace (#139)" + indentationShouldntCauseTrailingWhitespaceOnOtherwiseEmptyLines ] fusionDoesNotChangeRendering :: FusionDepth -> Property @@ -380,3 +382,11 @@ regressionUnboundedGroupedLineWithinAlign sdoc = layoutPretty (LayoutOptions Unbounded) doc expected = SChar 'x' (SLine 0 (SChar 'y' SEmpty)) in assertEqual "" expected sdoc + +indentationShouldntCauseTrailingWhitespaceOnOtherwiseEmptyLines :: Assertion +indentationShouldntCauseTrailingWhitespaceOnOtherwiseEmptyLines + = let doc :: Doc () + doc = indent 1 ("x" <> hardline <> hardline <> "y" <> hardline) + sdoc = layoutPretty (LayoutOptions Unbounded) doc + expected = SChar ' ' (SChar 'x' (SLine 0 (SLine 1 (SChar 'y' (SLine 0 SEmpty))))) + in assertEqual "" expected sdoc