Enable tab complete for '-Format' parameter of Get-Date#4835
Enable tab complete for '-Format' parameter of Get-Date#4835daxian-dbw merged 13 commits intoPowerShell:masterfrom
Conversation
If AllowAll==true 'ValidateElement' always pass all elements. Useful if we need enable IntelliSense (TabComplete) but effectively disable validation when a parameter can accept not only the listed values but also arbitrary. Ex.: Get-Date -Format
Add ValidateSet attribute to '-Format' parameter of Get-Date to enable IntelliSense (tab complete).
8244665 to
e7ea552
Compare
|
Should we use another attribute name just for the IntelliSense scenario? |
|
ValidateSet is a sealed. |
lzybkr
left a comment
There was a problem hiding this comment.
Thanks for thinking about the usability here - I agree we should do something here, just not like this.
| /// Useful if we need enable IntelliSense (TabComplete) but effectively disable validation | ||
| /// when a parameter can accept not only the listed values but also arbitrary. | ||
| /// Ex.: Get-Date -Format | ||
| /// </summary> |
There was a problem hiding this comment.
This doesn't feel right to me - you shouldn't use a Validation attribute if you aren't validating.
| /// Unix format string | ||
| /// </summary> | ||
| [Parameter(ParameterSetName = "net")] | ||
| [ValidateSetAttribute("FileDate", "FileDateUniversal", "FileDateTime", "FileDateTimeUniversal", AllowAll=true)] |
There was a problem hiding this comment.
I would suggest using an ArgumentCompleter attribute instead - it's a bit more cumbersome, but if this scenario makes sense (and I think it probably does), we can find some way to make it simpler.
There was a problem hiding this comment.
Do you suggest enhance ArgumentCompleter to support [ArgumentCompleter("FileDate", "FileDateUniversal", "FileDateTime", "FileDateTimeUniversal")] ?
There was a problem hiding this comment.
Just brainstorming here - but maybe a new attribute ArgumentCompletions that also implements IArgumentCompleter - this probably requires some additional code elsewhere, probably similar to the ValidateSet code for completion.
There was a problem hiding this comment.
A new attribute requires a lot of code. It seems easiest to add a new constructor public ArgumentCompleterAttribute(params string[] completeStrings)
Introduce new ArgumentCompleter constructor. Invoke the constructor in NativeCommandArgumentCompletion()
| /// </summary> | ||
| [Parameter(ParameterSetName = "net")] | ||
| [ValidateSetAttribute("FileDate", "FileDateUniversal", "FileDateTime", "FileDateTimeUniversal", AllowAll=true)] | ||
| [ArgumentCompleter("FileDate", "FileDateUniversal", "FileDateTime", "FileDateTimeUniversal")] |
There was a problem hiding this comment.
This is much better, but I think still a little weird, I still think it's worth considering adding a new attribute ArgumentCompletions. It seems like you could take your class StringArrayArgumentCompleter, rename it, make it an attribute, and either duplicate a little bit of logic around ValidateSet or ArgumentCompleter in the tab completion code.
There was a problem hiding this comment.
Is your only thought that ArgumentCompleter is a strange name and you want to rename it?
There was a problem hiding this comment.
I wouldn't rename ArgumentCompleter even if it is a strange name (which I suppose it is.)
It's a really minor thing, but to me, ArgumentCompleter implies some dynamic code to compute the completions, whereas ArgumentCompletions is static.
There was a problem hiding this comment.
I have missed that for a long time - the ability to easily complete a set without limiting the parameter to the completions.
Is it a reasonable compromise that you have to go IArgumentCompleter if you want to provide rich CompletionResults, or should be enable this with ArgumentCompletions too?
There was a problem hiding this comment.
Done next iteration.
This attribute is used to specify an argument completions for a parameter of a cmdlet or function without force throw unlike ValidateSetAttribute.
91b98ab to
ceb9385
Compare
lzybkr
left a comment
There was a problem hiding this comment.
Just a little cleanup and I think it looks good.
| { | ||
| if (wordToCompletePattern.IsMatch(str)) | ||
| { | ||
| yield return new CompletionResult(str, str, CompletionResultType.Text, str); |
There was a problem hiding this comment.
Should this be CompletionResultType.ParameterValue? I think that's the only place the attribute will have any effect.
| var argumentCompletionsAttribute = parameter.CompiledAttributes.OfType<ArgumentCompletionsAttribute>().FirstOrDefault(); | ||
| if (argumentCompletionsAttribute != null) | ||
| { | ||
| try |
There was a problem hiding this comment.
You are calling internal code which doesn't throw, so the try/catch is unnecessary.
| Metadata.ValidateNotNullFailure); | ||
| } | ||
|
|
||
| if (AllowAll == true) |
| /// Useful if we need enable IntelliSense (TabComplete) but effectively disable validation | ||
| /// when a parameter can accept not only the listed values but also arbitrary. | ||
| /// Ex.: Get-Date -Format | ||
| /// </summary> |
| { | ||
| result.IgnoreCase = s_attrArgToBoolConverter.Target(s_attrArgToBoolConverter, argValue); | ||
| } | ||
| else if (argumentName.Equals("AllowAll", StringComparison.OrdinalIgnoreCase)) |
lzybkr
left a comment
There was a problem hiding this comment.
Code changes are approved - but we should get a couple of tests for the new ArgumentCompletions attribute.
411123c to
f86c15a
Compare
f86c15a to
306fdc6
Compare
|
@iSazonov The tests look good, thanks! |
|
|
| } | ||
|
|
||
| AfterAll { | ||
| #Remove-Module -ModuleInfo $testModule |
There was a problem hiding this comment.
Did you forget to uncomment this?
There was a problem hiding this comment.
Yes 😄 Today tests is passed. I wonder - I don't change a code.
|
@lzybkr Thanks for great idea! |
Add ArgumentCompletions attribute to '-Format' parameter of Get-Date to enable
IntelliSense (tab complete).
Fix
-Formatparameter with named format values.Additional considerations
No tab completion test added for Get-Date because it seems we have no requirements to check tab completion for every parameter in all cmdlets.