Skip to content

RFC for expanded implicit line continuance feature #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

40 changes: 40 additions & 0 deletions 1-Draft/RFCNNNN-Implicit-Line-Continuance.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,49 @@ If the risk is deemed to be too high because of the risk with named unary operat
Pros: The @ symbol is familiar since it is used for splatting. Also, PSReadline could recognize when you're opting in to use this at the command prompt, only running the command if you hit enter twice (although this wouldn't be used nearly as often at the prompt -- it's really for scripts).
Cons: Users lose the benefit of not having to use any characters for line continuance.

Here's another alternative sigil to do the same thing that is a bit more literal:

```PowerShell
New-ADUser ...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of ... over @. I think the readability of ... is poor. My vision is bad and the ellipsis blends in with the line below it. Also it could be confused with (The Unicode ellipsis character). But I do like the idea of using something here and won't bike shed on it. I just want to call out the readability issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My current favorite is this alternative -- not the ellipsis specifically, but some sigil to tell the parser to parse the rest of the command in multi-line mode, meaning it would parse parameters/arguments until it encountered a command terminator (e.g. semi-colon, closing brace/bracket, etc.) or a blank line. It's minimal, transitioning to/from that syntax is as simple as adding/deleting the sigil and some newlines, and commands could be wrapped however the scripter wants, it would work in the interactive shell, and it would be completely non-breaking as long as the sigil was chosen carefully.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'm rather fond of using ~ as the continuation token here:

Get-ChildItem ~
    C:\
    -Filter *.ps*1
    -File
    -Recurse

Copy link
Contributor Author

@KirkMunro KirkMunro May 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, when I saw this on my phone without my glasses, I thought the sigil you proposed was -, which I liked at first, but later realized that it is already used for continuance in arithmetic expressions, so that's out. I'm less fond of ~, at least at first glance, but once we decide on an approach to take (assuming we get that far), we can discuss which sigil makes the most sense and share a bunch of options.

Copy link
Contributor

@Jaykul Jaykul May 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I made the suggestion about a character after trying it out. You guys aren't even thinking about it very hard, never mind actually trying it out. I believe the @ works because it's not valid syntax currently. All those others are already valid input.

> write-host -{ write-output 'hello' }
- hello

> Write-Host ...
...

> Write-Host ~
~

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'm rather fond of using ~ as the continuation token here:
Get-ChildItem ~
C:
-Filter .ps1
-File
-Recurse

In addition to Jaykul's Write-Host example, ~ is a shortcut for the current user's home folder. Get-ChildItem ~ will return items from that folder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jaykul actually I'm thinking about this RFC a ton. I just didn't come back to comment again after I replied when I realized neither - not ~ would work. In the case of my last comment, it is less about not thinking too hard, more about responding too quickly to another comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to mention that I rarely if ever use Write-Host (which I know you have used a lot), so some of those use cases never occurred to me. Of course that's why we have an RFC for this.

-Name 'Jack Robinson'
-GivenName 'Jack'
-Surname 'Robinson'
-SamAccountName 'J.Robinson'
-UserPrincipalName '[email protected]'
-Path 'OU=Users,DC=enterprise,DC=com'
-AccountPassword (Read-Host -AsSecureString 'Input Password')
-Enabled $true
```

Pros: ... is literal and familiar. The same PSReadline benefits listed for the previous example apply.
Cons: The same cons listed in the previous example apply.

1. Add support for optional features to PowerShell, and make this feature optional, rather than experimental.

The experimental feature is designed to be a temporary holding place until features are fully developed. There are advantages to having optional features as well, which users can opt into if they want the benefit. Ideally such functionality would have support for enabling optional features in both scripts and modules, so that the features could be used by script/module authors without impacting the experience of individual consumers of those scripts/modules. This alone (support for optional features) warrants another RFC, but assuming it is there and assuming such features can be turned on for scripts (via `#requires`?) and/or modules (via the manifest), scripters who want this capability could have it automatically turned on for new scripts/modules without risk to existing scripts/modules because they wouldn't have that feature enabled, thus preventing a breaking change. Anyone who wants this for existing scripts/modules could manually enable it and take on the responsibility of making their code work appropriately.

Pros: Allows the feature to be used without any breaking changes, and without extra continuance characters.
Cons: Requires optional feature work in PowerShell (an RFC that I'd be happy to write).

1. Add argument enclosure support to PowerShell.

One reader of this RFC who expressed their dislike for this functionality was pointing out that they don't like the fact that there is no terminator to the wrapped command parameters, so PowerShell needs to determine when the command ends based on lookahead. If preferable, new syntax could be added to allow for argument enclosures so that there is a defined terminator. For example, consider this syntax:

```PowerShell
New-ADUser -{
-Name 'Jack Robinson'
-GivenName 'Jack'
-Surname 'Robinson'
-SamAccountName 'J.Robinson'
-UserPrincipalName '[email protected]'
-Path 'OU=Users,DC=enterprise,DC=com'
-AccountPassword (Read-Host -AsSecureString 'Input Password')
-Enabled $true
}
```

What's interesting about this syntax is that these don't need to be just (named) parameter enclosures. They can be defined as argument enclosures, allowing scripters to put whatever they want on whichever lines they want, wrapping where it makes sense for them to do so, while using named parameters, positional parameters, or arguments (for external commands that don't have parameters).

Pros: Allows the feature to be used without any breaking changes (script blocks do not support negate or subtraction operators, so this new enclosure could be added without risk). Allows the scripter to wrap how they see fit, while still getting Intellisense and tab completion. Parameters and arguments are entered the same way they would be if they were all placed on one line (e.g. unlike splatting, parameter names are entered with dashes, no equals signs are required, etc.).
Cons: Requires a little extra syntax to make it work properly.