From 4e7607deb5383a4be421d16513f22325dc2e55fa Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Thu, 26 Nov 2020 11:42:31 -0500 Subject: [PATCH] repl: Display multi-line strings as heredocs The console and output formatter previously displayed multi-line strings with escaped newlines, e.g. `"hello\nworld\n"`. While this is a valid way to write the HCL string, it is not as common or as readable as using the heredoc syntax, e.g. < 0 { + operator = "<<-" + } + + // Default delimiter is "End Of Text" by convention + delimiter := "EOT" + +OUTER: + for { + // Check if any of the lines are in conflict with the delimiter. The + // parser allows leading and trailing whitespace, so we must remove it + // before comparison. + for _, line := range lines { + // If the delimiter matches a line, extend it and start again + if strings.TrimSpace(line) == delimiter { + delimiter = delimiter + "_" + continue OUTER + } + } + + // None of the lines match the delimiter, so we're ready + break + } + + // Write the heredoc, with indentation as appropriate. + var buf strings.Builder + + buf.WriteString(operator) + buf.WriteString(delimiter) + for _, line := range lines { + buf.WriteByte('\n') + buf.WriteString(strings.Repeat(" ", indent)) + buf.WriteString(line) + } + buf.WriteByte('\n') + buf.WriteString(strings.Repeat(" ", indent)) + buf.WriteString(delimiter) + + return buf.String(), true +} + func formatMappingValue(v cty.Value, indent int) string { var buf strings.Builder count := 0 diff --git a/repl/format_test.go b/repl/format_test.go index 108d32dc9..d0b6b8805 100644 --- a/repl/format_test.go +++ b/repl/format_test.go @@ -58,7 +58,28 @@ func TestFormatValue(t *testing.T) { }, { cty.StringVal("hello\nworld"), - `"hello\nworld"`, // Ideally we'd use heredoc syntax here for better readability, but we don't yet + `<