cue
cue copied to clipboard
spec: permit CUE comments inside multi-line strings
Is your feature request related to a problem? Please describe.
I often use fields that are multi-line strings (""") to specify the contents of files that are encoded in formats that the cue command currently can't emit. E.g. Dockerfiles, nginx configs, etc. Sometimes these strings are used verbatim, sometimes with interpolation, and sometimes with text/template.
In all these scenarios, I almost always need to leave comments for the next person who might change the string's contents. Very often, these comments are specific to certain regions of the file, thus leaving them in native CUE comments on the lines directly preceding the field requires the reader to read the comment ahead of the file's contents, and to break their flow when reading through the source, remembering to jump back to where the string begins as appropriate. Instead of that "jumpy" workflow, I usually choose to place comments inline, using the comment syntax of the file that I'm encoding.
This has a couple of drawbacks:
- The encoding may not permit comments.
- The comments persist through to the emitted file, which I /usually/ don't want to happen as that increases the risk that someone reading the emitted file will think that they have sufficient context to amend the file, in place. Whereas I need them to obey any "DO NOT EDIT" warning that I've placed at the top of the rendered file.
Describe the solution you'd like
I'd like multi-line strings to permit CUE comments that are preceded by an insufficient whitespace prefix (given the whitespace directly preceding the string's closing """) and not include them in the value of the multi-line string.
In other words, to allow this test to pass:
exec cue export file.cue
cmp stdout out
-- file.cue --
x: """
This is a multi-line string.
Here is another line.
// The next line is VERY important - don't change it!
This line looks unimportant.
"""
-- out --
{
"x": "This is a multi-line string.\nHere is another line.\nThis line looks unimportant."
}
Describe alternatives you've considered
As above:
- non-CUE comments that persist to the rendered output
- no comments at all
- CUE-field-level comments
Additional context
n/a
I personally think your suggested change to the spec would complicate the syntax for multiline strings a bit too much.
Here's one alternative with two multiline strings - note the needed newline as there are no leading or trailing newlines in multiline strings by design:
exec cue export file.cue
cmp stdout out
-- file.cue --
x: """
This is a multi-line string.
Here is another line.
""" +
"\n" + // The next line is VERY important - don't change it!
"""
This line looks unimportant.
"""
-- out --
{
"x": "This is a multi-line string.\nHere is another line.\nThis line looks unimportant."
}
Potentially we could also consider allowing inline-like comments, such as the following, as long as the comment expression doesn't result in an empty line:
exec cue export file.cue
cmp stdout out
-- file.cue --
x: """
This is a multi-line string.
Here is another line.
\(// The next line is VERY important - don't change it!)
This line looks unimportant.
"""
-- out --
{
"x": "This is a multi-line string.\nHere is another line.\nThis line looks unimportant."
}
I personally think your suggested change to the spec would complicate the syntax for multiline strings a bit too much.
JOOI from a spec or a consumer perspective?
Here's one alternative with two multiline strings
IMHO that feels quite fiddly, and puts me in mind of when I was first rather surprised by how Google suggested one should write literal multi-line JavaScript strings: https://google.github.io/styleguide/javascriptguide.xml?showone=Multiline_string_literals#Multiline_string_literals. Both feel ... sub-optimal.
we could also consider allowing inline-like comments
Whilst I still personally prefer the issue's opening idea of "insufficient whitespace prefix permits a CUE comment", how about this slight modification of the inline comment:
exec cue export file.cue
cmp stdout out
-- file.cue --
x: """
This is a multi-line string.
Here is another line.
\(// The next line is VERY important - don't change it!
This line looks unimportant.
"""
-- out --
{
"x": "This is a multi-line string.\nHere is another line.\nThis line looks unimportant."
}
In other words, if the first 4 characters (or 5+, if the escape delimiter has been redefined) are the opening of an expression, followed immediately by the start of a comment, then treat the rest of that line as a comment without requiring closing parens.
This would allow editors to reflow the comments more easily (it's just a 4-character "comment" prefix); readers to recognise comments through their prefix (as with your example); whilst allowing the implementation to rely on the newline to close the expression. There must be such a source newline, or the comment is on the last line of the string -- which feels functionally identical.