Note: This idea was first proposed by @bergmeister and fleshed out by @lzybkr in https://github.com/PowerShell/PowerShell/issues/2337#issuecomment-391152107, but only in the context of a proposal focused on something different (allowing indentation of the closing delimiter of here-strings).
To complement the existing raw / semi-raw, invariably _multi-line_ here-string literals (@'<newline>...<newline>'@
/ @"<newline>...<newline>"@
), it would be convenient to have a _single-line_ variant.
For lack of a better term I'll call the new variant a _raw string literal_.
For instance, here's how you could express verbatim string 6' 2"
:
# Note: leading and trailing whitespace inside the value will be ignored.
# single-quoted
@' 6' 2" '@
# double-quoted - as with double-quoted here-strings, string interpolation and `-escaping would work.
@" $feet' 2" "@
To avoid the need for escaping, allow a _variable_ number of quotes in the delimiter to avoid the need for escaping; e.g.:
@'' using @' in here is now fine ''@
A use case that would benefit is wanting to pass a command line written for the native shell _as-is_ to it (see also: #13068); e.g. (on Unix):
# WISHFUL THINKING
sh -c @' python -c 'print("hi")' | cat -n '@
Backward compatibility assessment:
Since with the current here-string literals no (non-whitespace) characters are allowed on the same line after the opening delimiter, and given that trying to do that is currently a _syntax error_, this new string-literal variant is safe to introduce.
Disambiguation:
Anything that starts with @'
or @"
and is _followed by non-whitespace characters on the same line_ is interpreted as the new _raw_ string literal, requiring the closing delimiter to be _on the same line_.
Insignificant leading and trailing whitespace:
Ignoring whitespace surrounding the value serves two purposes:
@' 6' 2" '@
vs. @'6' 2"'@
)@'' @' is fine ''@
), ignoring surrounding whitespace solves the problem of enclosed values _starting or ending with a quote_ that would otherwise break the syntax (e.g., to embed verbatim 'hi
, @''hi'@
wouldn't work syntactically, but @' 'hi '@
- with surrounding whitespace stripped on parsing - does.@TSlivede proposes the following alternatives, which consider all whitespace significant, albeit at the expense of the visual separation between the delimiters and the value:
@
symbol - see below.Values that need surrounding whitespace to be significant:
In cases where you need the enclosed values _start and/or end with whitespace_, the following solutions are possible:
Use the _double-quoted_ form, where `
-escaping can be used to escape the spaces.
E.g., to get verbatim <space>a"b'<space>
, you'd use @"` a"b'` "@
.
Alternatively, @TSlivede proposes considering only _one_ leading/trailing space insignificant, in which case you merely need to add one extra space each to values with significant whitespace, in both the single- and double-quoted forms; e.g., @'<space> a"b <space>'@
and @"<space> a"b <space>"@
. However, a concern is that user may not expect that only a _specific number_ (i.e., one) of spaces is insignificant; see below.
Alternatively, use the established multi-line here-string forms, where all whitespace is significant.
Thanks for creating an explicit issue for this!
Alternative suggestion regarding the removal of "Insignificant leading and trailing whitespace":
How about considering only a maximum of one leading space and one trailing space as "insignificant" and remove it?
This would still allow this:
- It makes it easier to visually distinguish the delimiters from the enclosed value (e.g.,
@' 6' 2" '@
vs.@'6' 2"'@
)- Since supporting a variable number of quotes in the delimiter is desirable (e.g.,
@'' @' is fine ''@
), ignoring surrounding whitespace solves the problem of enclosed values starting or ending with a quote that would otherwise break the syntax (e.g., to embed verbatim'hi
,@''hi'@
wouldn't work syntactically, but@' 'hi '@
- with surrounding whitespace stripped on parsing - does.
And it would also improve "Values that need surrounding whitespace to be significant":
Just put one more space to the beginning and one more to the end.
Thanks, @TSlivede, I've folded your suggestion into the OP. I like it, but a slight concern is that the fact that the behavior is tied to a _specific number_ of spaces, i.e., exactly one, could be a bit obscure, and that people may be more used to _any number_ of leading/trailing spaces being insignificant, such as in inline code elements enclosed in `
in Markup.
people may be more used to any number of leading/trailing spaces being are insignificant
Yes you are right, the syntax I suggested might be very surprising to new users, maybe it's not such a good idea after all.
It could for example be especially problematic, if someone wants a string leading with e.g. 4 spaces. To test if spaces are preserved he enters @'聽聽聽聽test string'@
(4 spaces) and powershell prints 聽聽聽test string
(three spaces), which looks very similar to four leading spaces. That user would probably not notice the missing space and would now have a very subtle bug in his code...
Good points. I take it then that this would require at least the initial leading space to be escaped with `
?
@vexx32, yes, but note that the use of `
for escaping requires a switch to the _double-quoted_ form, because in the single-quoted one the `
would be a literal that is retained. Using a single-quoted (invariably multi-line) here-string instead avoids that.
@TSlivede :) I've unindented the paragraph, and I've also added our (later) concern about the suggestion expressed therein.
Another alternative idea:
Allow only a maximum of three quotes in the delimiters and don't remove leading/trailing whitespace.
This way we would lose the visual advantage
- It makes it easier to visually distinguish the delimiters from the enclosed value (e.g.,
@' 6' 2" '@
vs.@'6' 2"'@
)
(@' 6' 2" '@
and @'6' 2"'@
would not be equivalent)
But we would gain an easy option for leading or trailing significant whitespace.
Leading quotes would also be easy: As only a maximum of three quotes are considered part of the string delimiter, the fourth quote would be a literal quote.
e.g., to embed verbatim 'hi
one could use @''''hi'''@
As with my previous suggestion the behavior is tied to a specific number of quotes (not spaces in this case 馃槈). But three quotes is something users might already have seen for here strings: python, kotlin, scala, groovy
Addition to that suggestion: To allow embedding literal '''@
maybe allow multiple (unlimited?) @
symbols in the string delimiters. E.g.:
@@'some string containing >>>'@<<< - delimited with multiple @-symbols'@@
Most helpful comment
Addition to that suggestion: To allow embedding literal
'''@
maybe allow multiple (unlimited?)@
symbols in the string delimiters. E.g.: