From 073e9b2aed0f855ce26bd3a26dab044c0c17c817 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 17 Sep 2020 17:58:04 +0200 Subject: [PATCH] lib/generators.toPretty: Improved string printing, handling newlines --- lib/generators.nix | 14 +++++++++++++- lib/tests/misc.nix | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/generators.nix b/lib/generators.nix index 23a74c757f8..81bedd13d80 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -213,7 +213,19 @@ rec { outroSpace = if multiline then "\n${indent}" else " "; in if isInt v then toString v else if isFloat v then "~${toString v}" - else if isString v then ''"${libStr.escape [''"''] v}"'' + else if isString v then + let + # Separate a string into its lines + newlineSplits = filter (v: ! isList v) (builtins.split "\n" v); + # For a '' string terminated by a \n, which happens when the closing '' is on a new line + multilineResult = "''" + introSpace + concatStringsSep introSpace (lib.init newlineSplits) + outroSpace + "''"; + # For a '' string not terminated by a \n, which happens when the closing '' is not on a new line + multilineResult' = "''" + introSpace + concatStringsSep introSpace newlineSplits + "''"; + # For single lines, replace all newlines with their escaped representation + singlelineResult = "\"" + libStr.escape [ "\"" ] (concatStringsSep "\\n" newlineSplits) + "\""; + in if multiline && length newlineSplits > 1 then + if lib.last newlineSplits == "" then multilineResult else multilineResult' + else singlelineResult else if true == v then "true" else if false == v then "false" else if null == v then "null" diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 4fed8ef01c9..813a8e7f815 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -450,7 +450,9 @@ runTests { int = 42; float = 0.1337; bool = true; + emptystring = ""; string = ''fno"rd''; + newlinestring = "\n"; path = /. + "/foo"; null_ = null; function = x: x; @@ -463,7 +465,9 @@ runTests { int = "42"; float = "~0.133700"; bool = "true"; + emptystring = ''""''; string = ''"fno\"rd"''; + newlinestring = "\"\\n\""; path = "/foo"; null_ = "null"; function = "<λ>"; @@ -478,6 +482,16 @@ runTests { expr = mapAttrs (const (generators.toPretty { })) rec { list = [ 3 4 [ false ] ]; attrs = { foo = null; bar.foo = "baz"; }; + newlinestring = "\n"; + multilinestring = '' + hello + there + test + ''; + multilinestring' = '' + hello + there + test''; }; expected = rec { list = '' @@ -495,6 +509,19 @@ runTests { }; foo = null; }''; + newlinestring = "''\n \n''"; + multilinestring = '' + ''' + hello + there + test + '''''; + multilinestring' = '' + ''' + hello + there + test'''''; + }; };