Originally posted to https://github.com/PowerShell/vscode-powershell/issues/1939, as it was originally regarding completions in VS Code, but the completions come from PowerShell, and were confirmed at the command prompt.
try:
Enter [PSDefaultValueAttribute, press [TAB] (completion), the value inserted is PSDefaultValue. This is good.
Enter [FlagsAttribute, press [TAB] (completion), the value actually inserted is System.FlagsAttribute. I expected just Flags.
Similar result for [Ordered.
Enter [PSCustomObject a completion here changes it to pscustomobject. For some reason VS Code displays PSObject as the completion, but when chosen, the same result occurs (pscustomobject)
Why the difference between the completions for these objects?
So far the discussion has stated that PSDefaultValue is defined as an accelerator, and pscustomobject is the accelerator for [System.Management.Automation.PSObject], hence the discrepancy in VS Code, and ordered is just hard set in the parser. That doesn't explain flags so far.
[Flags()] is an attribute with full name FlagsAttribute... Not sure why it's completing the System portion specifically but although attributes can omit the Attribute suffix in their name in C#, for example, PS doesn't have quite the same support for it, and there are some cases where the proper name is necessary.
The rules there, however, aren't clear, but I would expect that the tab completion there is suffering from a similar root cause.
@SeeminglyScience and @rjmholt both pretty well detailed whats happening with this on the vscode-powershell version of this thread. (link in original post)
My issue here is that the actions of the completions provide confusion to the user. This is more common in VS Code (or other editors) than on the command line, where the completer is more likely to be tripped accidentally. I suspect this was partially the goal of the type accelerations, as it improved the interactive experience with the short-hand types, and gave data to a completion engine at the same time.
I might suggest, that since "keywords" such as [ordered] and [flags()] are propagated via documentation, that they should be, somehow, part of the completion logic.
For instance the completion options for [ordered (on my system) should be
[ordered (even if [ORDERED was entered)[System.Collections.Specialized.OrderedDictionary[System.Linq.OrderedParallelQuery[flags completion should maybe be handled in a similar way, even though its truly an attribute and not a language keyword.
Additionally, all of the system.*Attribute attributes should be included in the same format that PowerShell permits them, providing, maybe, a cross check to make sure that a type name doesn't also exist without the Attribute suffix. Of course, this would probably eliminate much of the use of the type accelerators feature.
Additionally, all of the system.*Attribute attributes should be included in the same format that PowerShell permits them, providing, maybe, a cross check to make sure that a type name doesn't also exist without the Attribute suffix. Of course, this would probably eliminate much of the use of the type accelerators feature.
The problem is that PowerShell only permits that format in attribute expressions. Typically when command completion is triggered for an attribute, it's not actually an AttributeAst yet. Until that () is typed, it's a TypeExpressionAst or a TypeConstraintAst. Both of those do very different things and resolving all attributes without their suffix could lead to a lot of confusing scenarios.
Same thing applies to ordered. It's only valid in a ConvertExpressionAst, but most of the time it's impossible to tell that you want that until you've typed the rest of the expression. This one I'm kind of on the fence about, but I lean towards thinking it would do more harm than good.
Whether a given completion is completely valid in context is not to be considered 100% relevant to the completion, unfortunately it cannot possibly know every possible context, so I suggest that those completions should be available, because they could be possible. The user will still need to make some choice. I did not suggest leaving the original completions with the attribute suffix out, only that the completions for without the suffix should be provided because they are possible.
Unfortunately, the completion logic doesn't work if the () is already present. So we have yet another failure.
so I suggest that those completions should be available, because they could be possible
Worth noting that more/noisier completions are a degradation of the completion experience; you want fewer and more accurate completions.
The completion experience was originally written for interactive usage, where you're editing at the end of the script.
Given that it's being used quite heavily in editor contexts now, I think it's worth investigating completions mid-script.
Most helpful comment
The problem is that PowerShell only permits that format in attribute expressions. Typically when command completion is triggered for an attribute, it's not actually an
AttributeAstyet. Until that()is typed, it's aTypeExpressionAstor aTypeConstraintAst. Both of those do very different things and resolving all attributes without their suffix could lead to a lot of confusing scenarios.Same thing applies to
ordered. It's only valid in aConvertExpressionAst, but most of the time it's impossible to tell that you want that until you've typed the rest of the expression. This one I'm kind of on the fence about, but I lean towards thinking it would do more harm than good.