diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 90ee8f574..f47cdefa6 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -1,5 +1,7 @@ {-# language CPP #-} {-# language AllowAmbiguousTypes #-} +{-# language ViewPatterns, PatternSynonyms, OverloadedStrings #-} + {-# options_ghc -fno-warn-name-shadowing #-} @@ -99,20 +101,27 @@ wrapPath op sub = ("\"${" <> withoutParens sub <> "}\"") (wasPath sub) + +infixr 5 :< +pattern (:<) :: Char -> Text -> Text +pattern t :< ts <- (Text.uncons -> Just (t, ts)) + where (:<) = Text.cons + +escapeDoubleQuoteString :: Text -> Text +escapeDoubleQuoteString ('"': escapeDoubleQuoteString xs +escapeDoubleQuoteString ('$':<'{': escapeDoubleQuoteString xs +escapeDoubleQuoteString ('$': escapeDoubleQuoteString xs +escapeDoubleQuoteString a = a + + prettyString :: NString (NixDoc ann) -> Doc ann prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" where - -- It serializes Text -> String, because the helper code is done for String, - -- please, can someone break that code. - prettyPart (Plain t) = pretty . foldMap escape . toString $ t + prettyPart (Plain t) = pretty $ escapeDoubleQuoteString t prettyPart EscapedNewline = "''\\n" prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" - escape '"' = "\\\"" - escape x = - maybe - (one x) - (('\\' :) . one) - (toEscapeCode x) prettyString (Indented _ parts) = group $ nest 2 $ vcat ["''", content, "''"] where @@ -382,6 +391,7 @@ prettyNThunk t = "(" <> fold (one "thunk from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")" ] + -- | This function is used only by the testing code. printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text printNix = iterNValueByDiscardWith thk phi @@ -390,7 +400,7 @@ printNix = iterNValueByDiscardWith thk phi phi :: NValue' t f m Text -> Text phi (NVConstant' a ) = atomText a - phi (NVStr' ns) = show $ ignoreContext ns + phi (NVStr' ns) = "\"" <> escapeDoubleQuoteString (ignoreContext ns) <> "\"" phi (NVList' l ) = "[ " <> unwords l <> " ]" phi (NVSet' _ s) = "{ " <> diff --git a/tests/NixLanguageTests.hs b/tests/NixLanguageTests.hs index bfbb618b1..a4e29d603 100644 --- a/tests/NixLanguageTests.hs +++ b/tests/NixLanguageTests.hs @@ -61,6 +61,7 @@ newFailingTests = Set.fromList , "eval-okay-path" -- #128 , "eval-okay-types" , "eval-okay-fromTOML" + , "eval-okay-ind-string" -- #1000 #610 ] -- | Upstream tests that test cases that HNix disaded as a misfeature that is used so rarely diff --git a/tests/PrettyTests.hs b/tests/PrettyTests.hs index cafa6e707..0af007264 100644 --- a/tests/PrettyTests.hs +++ b/tests/PrettyTests.hs @@ -23,7 +23,7 @@ case_string_antiquotation = do assertPretty (mkStr "echo $foo") - "\"echo \\$foo\"" + "\"echo $foo\"" assertPretty (mkStr "echo ${foo}") "\"echo \\${foo}\"" diff --git a/tests/eval-compare/ind-string-18.nix b/tests/eval-compare/ind-string-18.nix new file mode 100644 index 000000000..8f992e9a2 --- /dev/null +++ b/tests/eval-compare/ind-string-18.nix @@ -0,0 +1,2 @@ +# to observe the upstream nix behavior for dollar sign excape in doublequote string +"\${foo \$ $foo" diff --git a/tests/eval-compare/ind-string-19.nix b/tests/eval-compare/ind-string-19.nix new file mode 100644 index 000000000..aec913bd8 --- /dev/null +++ b/tests/eval-compare/ind-string-19.nix @@ -0,0 +1,4 @@ +# to observe the upstream nix behavior for dollar excape in Indented string +'' +''$ $ ''${ +''