@@ -1087,21 +1087,23 @@ prettyCharacterSet characterSet expression =
1087
1087
angles . map prettyAlternative . Dhall.Map. toList
1088
1088
1089
1089
prettyChunks :: Pretty a => Chunks Src a -> Doc Ann
1090
- prettyChunks (Chunks a b) =
1091
- if anyText (== ' \n ' )
1092
- then
1090
+ prettyChunks chunks@ (Chunks a b)
1091
+ | anyText (== ' \n ' ) =
1093
1092
if anyText (/= ' \n ' )
1094
1093
then long
1095
1094
else Pretty. flatAlt long short
1096
- else short
1095
+ | otherwise =
1096
+ short
1097
1097
where
1098
1098
long =
1099
1099
Pretty. align
1100
1100
( literal " ''" <> Pretty. hardline
1101
1101
<> Pretty. align
1102
- (foldMap prettyMultilineChunk a <> prettyMultilineText b)
1102
+ (foldMap prettyMultilineChunk a' <> prettyMultilineText b' )
1103
1103
<> literal " ''"
1104
1104
)
1105
+ where
1106
+ Chunks a' b' = multilineChunks chunks
1105
1107
1106
1108
short =
1107
1109
literal " \" " <> foldMap prettyChunk a <> literal (prettyText b <> " \" " )
@@ -1136,6 +1138,43 @@ prettyCharacterSet characterSet expression =
1136
1138
1137
1139
prettyText t = literal (Pretty. pretty (escapeText_ t))
1138
1140
1141
+
1142
+ -- | Prepare 'Chunks' for multi-line formatting by interpolating characters that
1143
+ -- may not appear in multi-line strings directly.
1144
+ --
1145
+ -- >>> multilineChunks (Chunks [] "\n\NUL\b\f\t")
1146
+ -- Chunks [("\n",TextLit (Chunks [] "\NUL\b\f"))] "\t"
1147
+ multilineChunks :: Chunks Src a -> Chunks Src a
1148
+ multilineChunks (Chunks as0 b0) = Chunks as1 b1
1149
+ where
1150
+ as1 = foldr f (map toPair bs) as0
1151
+
1152
+ (bs, b1) = splitOnPredicate predicate b0
1153
+
1154
+ predicate c = Data.Char. isControl c && c /= ' ' && c /= ' \t ' && c /= ' \n '
1155
+
1156
+ f (t0, e) pairs = case splitOnPredicate predicate t0 of
1157
+ (ts1, t1) -> map toPair ts1 ++ (t1, e) : pairs
1158
+
1159
+ toPair (t0, t1) = (t0, TextLit (Chunks [] t1))
1160
+
1161
+ -- | Split `Text` on a predicate, preserving all parts of the original string.
1162
+ --
1163
+ -- >>> splitOnPredicate (== 'x') ""
1164
+ -- ([],"")
1165
+ -- >>> splitOnPredicate (== 'x') " xx "
1166
+ -- ([(" ","xx")]," ")
1167
+ -- >>> splitOnPredicate (== 'x') "xx"
1168
+ -- ([("","xx")],"")
1169
+ --
1170
+ -- prop> \(Fun _ p) s -> let {t = Text.pack s; (as, b) = splitOnPredicate p t} in foldMap (uncurry (<>)) as <> b == t
1171
+ splitOnPredicate :: (Char -> Bool ) -> Text -> ([(Text , Text )], Text )
1172
+ splitOnPredicate p t = case Text. break p t of
1173
+ (a, " " ) -> ([] , a)
1174
+ (a, b) -> case Text. span p b of
1175
+ (c, d) -> case splitOnPredicate p d of
1176
+ (e, f) -> ((a, c) : e, f)
1177
+
1139
1178
-- | Pretty-print a value
1140
1179
pretty_ :: Pretty a => a -> Text
1141
1180
pretty_ = prettyToStrictText
@@ -1208,3 +1247,8 @@ layoutOpts :: Pretty.LayoutOptions
1208
1247
layoutOpts =
1209
1248
Pretty. defaultLayoutOptions
1210
1249
{ Pretty. layoutPageWidth = Pretty. AvailablePerLine 80 1.0 }
1250
+
1251
+
1252
+ {- $setup
1253
+ >>> import Test.QuickCheck (Fun(..))
1254
+ -}
0 commit comments