Skip to content

Commit

Permalink
cue/format: indent multiline string literals based on context.
Browse files Browse the repository at this point in the history
Change-Id: Ic58d29dfa347a2f0b3642e56676c2c944dbb8b2d
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7283
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Oct 3, 2020
1 parent c886094 commit 2ac4d85
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 67 deletions.
6 changes: 3 additions & 3 deletions cmd/cue/cmd/testdata/script/import_files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ name: "booster"
replicas: 1
kind: "Service"
name: """
supplement
foo
"""
supplement
foo
"""
json: "[1, 2]"
-- import/services.jsonl --
{
Expand Down
6 changes: 3 additions & 3 deletions cmd/cue/cmd/testdata/script/import_hoiststr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ service: {
"supplement\nfoo": [{
kind: "Service"
name: """
supplement
foo
"""
supplement
foo
"""
json: json656e63.Marshal(_cue_json)
let _cue_json = [1, 2]
}]
Expand Down
11 changes: 11 additions & 0 deletions cue/format/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/literal"
"cuelang.org/go/cue/token"
)

Expand Down Expand Up @@ -116,6 +117,16 @@ func (p *printer) Print(v interface{}) {
case *ast.BasicLit:
data = x.Value
switch x.Kind {
case token.STRING:
// TODO: only do this when simplifying. Right now this does not
// give the right result, but it should be better if:
// 1) simplification is done as a separate step
// 2) simplified structs are explicitly referenced separately
// in the AST.
if p.indent < 6 {
data = literal.IndentTabs(data, p.indent+1)
}

case token.INT:
if len(data) > 1 &&
data[0] == '0' &&
Expand Down
33 changes: 33 additions & 0 deletions cue/literal/indent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2020 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package literal

import "strings"

// IndentTabs takes a quoted string and reindents it for the given indentation.
// If a string is not a multiline string it will return the string as is.
func IndentTabs(s string, n int) string {
indent := tabs(n)

qi, _, _, err := ParseQuotes(s, s)
if err != nil || !qi.multiline || qi.whitespace == indent {
return s
}

search := "\n" + qi.whitespace
replace := "\n" + indent

return strings.ReplaceAll(s, search, replace)
}
55 changes: 55 additions & 0 deletions cue/literal/indent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2020 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package literal

import (
"testing"
)

func TestIndentTabs(t *testing.T) {
testCases := []struct {
in string
out string
}{{
in: `"""
foo
bar
"""`,
out: `"""
foo
bar
"""`,
}, {
in: `"""
foo
bar
"""`,
out: `"""
foo
bar
"""`,
}, {
in: `""`,
out: `""`,
}}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {
got := IndentTabs(tc.in, 3)
if got != tc.out {
t.Errorf("got %s; want %s", got, tc.out)
}
})
}
}
15 changes: 9 additions & 6 deletions cue/literal/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,21 @@ type Form struct {

// WithTabIndent returns a new Form with indentation set to the given number
// of tabs. The result will be a multiline string.
func (f Form) WithTabIndent(tabs int) Form {
if tabs < len(tabIndent) {
f.indent = tabIndent[:tabs]
} else {
f.indent = strings.Repeat("\t", tabs)
}
func (f Form) WithTabIndent(n int) Form {
f.indent = tabs(n)
f.multiline = true
return f
}

const tabIndent = "\t\t\t\t\t\t\t\t\t\t\t\t"

func tabs(n int) string {
if n < len(tabIndent) {
return tabIndent[:n]
}
return strings.Repeat("\t", n)
}

// WithOptionalIndent is like WithTabIndent, but only returns a multiline
// strings if it doesn't contain any newline characters.
func (f Form) WithOptionalTabIndent(tabs int) Form {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ configMap: alertmanager: {
slack_configs: [{
channel: "#cloudmon"
text: """
{{ range .Alerts }}{{ .Annotations.description }}
{{ end }}
"""
{{ range .Alerts }}{{ .Annotations.description }}
{{ end }}
"""
send_resolved: true
}]
}]
Expand Down
78 changes: 39 additions & 39 deletions internal/core/export/testdata/strings.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ c: d: a

-- out/definition --
a: """
multi
line
"""
multi
line
"""
b: "message: \(a)!"
c: {
d: a
Expand All @@ -27,68 +27,68 @@ c: {
== Simplified
{
a: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
}
}
== Raw
{
a: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
}
}
== Final
{
a: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
}
}
== All
{
a: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
b: """
message: multi
line!
"""
c: {
d: """
multi
line
"""
}
}
26 changes: 13 additions & 13 deletions internal/third_party/yaml/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,26 +205,26 @@ apple: "newline"`,
"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
`scalar: """
literal
literal
\ttext
\ttext
"""`,
"""`,
},

// Folded block scalar
{
"scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n",
`scalar: """
folded line
next line
* one
* two
folded line
next line
* one
* two
last line
last line
"""`,
"""`,
},

// Structs
Expand Down Expand Up @@ -456,10 +456,10 @@ b: {
` Line separator\u2028\` + "\n" +
` Paragraph separator\u2029"` + "\n",
`"""
Generic line break (no glyph)
Generic line break (glyphed)
Line separator\u2028Paragraph separator\u2029
"""`,
Generic line break (no glyph)
Generic line break (glyphed)
Line separator\u2028Paragraph separator\u2029
"""`,
},

// bug 1243827
Expand Down

0 comments on commit 2ac4d85

Please sign in to comment.