Skip to content

Commit 60e4732

Browse files
authored
refactor pretty.hs to avoid using Text -> String
Using ViewPatterns, PatternSynonyms, OverloadedStrings to achieve a readable code `escapeDoubleQuoteString` to escape nix double quoted string in both `prettyString` and `printNix`
1 parent 8671d5a commit 60e4732

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

src/Nix/Pretty.hs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{-# language CPP #-}
22
{-# language AllowAmbiguousTypes #-}
3+
{-# language ViewPatterns, PatternSynonyms, OverloadedStrings #-}
4+
35

46
{-# options_ghc -fno-warn-name-shadowing #-}
57

@@ -99,21 +101,27 @@ wrapPath op sub =
99101
("\"${" <> withoutParens sub <> "}\"")
100102
(wasPath sub)
101103

104+
105+
infixr 5 :<
106+
pattern (:<) :: Char -> Text -> Text
107+
pattern t :< ts <- (Text.uncons -> Just (t, ts))
108+
where (:<) = Text.cons
109+
110+
escapeDoubleQuoteString :: Text -> Text
111+
escapeDoubleQuoteString ('"':<xs) = "\\\"" <> escapeDoubleQuoteString xs
112+
escapeDoubleQuoteString ('$':<'{':<xs) = "\\${" <> escapeDoubleQuoteString xs
113+
escapeDoubleQuoteString ('$':<xs) = '$' :< escapeDoubleQuoteString xs
114+
escapeDoubleQuoteString (x:<xs) = maybe (one x) (('\\' :<) . one) (toEscapeCode x)
115+
<> escapeDoubleQuoteString xs
116+
escapeDoubleQuoteString a = a
117+
118+
102119
prettyString :: NString (NixDoc ann) -> Doc ann
103120
prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\""
104121
where
105-
-- It serializes Text -> String, because the helper code is done for String,
106-
-- please, can someone break that code.
107-
prettyPart (Plain t) = pretty . dollarEscape . toText . foldMap escape . toString $ t
122+
prettyPart (Plain t) = pretty $ escapeDoubleQuoteString t
108123
prettyPart EscapedNewline = "''\\n"
109124
prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}"
110-
escape '"' = "\\\""
111-
escape '$' = "$" -- do not print $ as \$ if no { is following
112-
escape x =
113-
maybe
114-
(one x)
115-
(('\\' :) . one)
116-
(toEscapeCode x)
117125
prettyString (Indented _ parts) = group $ nest 2 $ vcat
118126
["''", content, "''"]
119127
where
@@ -383,9 +391,6 @@ prettyNThunk t =
383391
"(" <> fold (one "thunk from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")"
384392
]
385393

386-
-- | dollarEscape for double quoted string
387-
dollarEscape :: Text -> Text
388-
dollarEscape = replace "${" "\\${"
389394

390395
-- | This function is used only by the testing code.
391396
printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text
@@ -395,7 +400,7 @@ printNix = iterNValueByDiscardWith thk phi
395400

396401
phi :: NValue' t f m Text -> Text
397402
phi (NVConstant' a ) = atomText a
398-
phi (NVStr' ns) = dollarEscape $ show $ ignoreContext ns
403+
phi (NVStr' ns) = "\"" <> escapeDoubleQuoteString (ignoreContext ns) <> "\""
399404
phi (NVList' l ) = "[ " <> unwords l <> " ]"
400405
phi (NVSet' _ s) =
401406
"{ " <>

0 commit comments

Comments
 (0)