Open PrzemyslawKlys opened 4 years ago
Thanks @PrzemyslawKlys for the detailed information, apologies for my confusion but can you please clarify the GIF...what are you expecting to see on line 10 that you are not seeing? Thanks!
Notice how 2nd element for Test parameter doesnt have proper autocompletion. Its just some cache from code not autocompletion. I have this behavior for validateset, enums, and so on. It works if its single entry. As soon as i expect array of entries only first one works. But again... not always. Works fine on line 14, and on line 10 same parameter for same command gives junk on 2nd and 3rd element.
Thanks @PrzemyslawKlys we are trying to determine whether this issue is occurring in PowerShell or in Editor Services, but it is a bit difficult for us to check without the full program. If you take this program and find the offset of where your completion is in relation to the script, you should be able to use tabexpansion2 to determine if the error in completion reproduces.
TabExpansion2 -inputScript @'
import-module MyModule
get-process -Name
get-childitem
'@ -cursorColumn 41 | %{ $_.CompletionMatches }
I am getting some errors when trying to replicate it using your code, but even for the simple stuff I can replicate it.
function New-Function {
[cmdletBinding()]
param(
[validateSet('New', 'Old', 'Other')][string[]] $Test1,
[validateSet('New', 'Old', 'Other')][string[]] $Test2
)
}
New-Function -Test1 New, Old -Test2 New,
New-Function -Test1 New -Test2 New
New-Function -Test2 New, Old, Other -Test1 Other, New, Old
<#
New-HTMLDiagram {
New-DiagramNode -IconColor
New-DiagramNode -IconColor AirForceBlue, AlbescentWhite -IconBrands accessible-icon
}
#>
1602058787-8d37b9bb-1adf-4331-8a15-9bf79b06e5f41602056586158.zip
Usually it seems I can replicate it if I try to edit something that's not last but is in the beginning of the file. For example if I start typing New-Function on line 8 it works, on line 9 it works and if I come back to line 7 and do the same thing it doesn't work anymore on 2nd and more entries.
But if you take one of the scripts where completion isn't working from your examples, turn it into a string, and send it through to TabExpansion2
with the right offset (you'll need to calculate that -- although picking some values and refining them based on output helps), do you see the right completion or no?
If it doesn't replicate with TabExpansion2
, it's a bug in our server engine, but if it does, it's a bug in the completion logic.
I don't know how to calculate offset :) So if you can provide me details...
I just replicated it on the simple code (no need for my fancy modules):
function New-Function {
[cmdletBinding()]
param(
[validateSet('New', 'Old', 'Other')][string[]] $Test1,
[validateSet('New', 'Old', 'Other')][string[]] $Test2
)
}
New-Function -Test1 New, Old -Test2 New,
New-Function -Test1 New -Test2 New
New-Function -Test2 New, Old, Other -Test1 Other, New, Old
But you need to start editing from bottom to top, like I am showing on the gifs. It seems to work if it's 1st entry, 2nd entry, but as soon as I go back to 1st entry and try to modify it, it no longer works correctly.
I don't know how to calculate offset :) So if you can provide me details...
It's the index into the string of your script, so you have to add up all the line lengths above it, plus the column offset.
Something like this:
function Get-Offset
{
param(
[Parameter(Mandatory)]
[string]
$Str,
[Parameter(Mandatory)]
[int]
$Line,
[Parameter(Mandatory)]
[int]
$Column
)
$i = -1
$currLine = 0
while ($i -lt $Str.Length -and $currLine -lt $Line)
{
$i = $Str.IndexOf("`n", $i + 1)
if ($i -le -1)
{
throw "Line out of range"
}
if ($i + 1 -lt $Str.Length -and $Str[$i + 1] -eq "`r")
{
$i++
}
$currLine++
}
return $i + $Column - 1
}
VSCode will tell you the line and column of your cursor, but in 1-based form, so just subtract 1 from the line and column
I tried, I really tried.
[string] $Script1 = Get-Content -Path $PSScriptRoot\Test7.ps1 -Raw
TabExpansion2 -inputScript $Script1 -cursorColumn 269 | ForEach-Object { $_.CompletionMatches }
Where Test7.ps1
function New-Function {
[cmdletBinding()]
param(
[validateSet('New', 'Old', 'Other')][string[]] $Test1,
[validateSet('New', 'Old', 'Other')][string[]] $Test2
)
}
New-Function -Test1 New -Test2 New
New-Function -Test1 New, Old -Test2 New
New-Function -Test1 New, Old -Test2 New
function Get-Offset {
param(
[Parameter(Mandatory)][string]$Str,
[Parameter(Mandatory)] [int] $Line,
[Parameter(Mandatory)] [int] $Column
)
$i = -1
$currLine = 0
while ($i -lt $Str.Length -and $currLine -lt $Line) {
$i = $Str.IndexOf("`n", $i + 1)
if ($i -le -1) {
throw "Line out of range"
}
if ($i + 1 -lt $Str.Length -and $Str[$i + 1] -eq "`r") {
$i++
}
$currLine++
}
return $i + $Column - 1
}
ForEach-Object : Cannot bind parameter 'RemainingScripts'. Cannot convert the "" value of type "System.String" to type "System.Management.Automation.ScriptBlock".
At C:\Support\GitHub\PSWriteHTML\Ignore\TestingFill.ps1:3 char:101
+ ... -cursorColumn 269 | ForEach-Object { $_.CompletionMatches }
+ ~~~~
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.ForEachObjectCommand
Do you have a stack trace for the error? It might be that the completer has an error in it and it's bubbling up -- that might also explain why completions only work sometimes.
I can confirm it fails in ISE as well.
If you try to autocomplete line 8 after new it won't do anything in ISE.
function New-Function {
[cmdletBinding()]
param(
[validateSet('New', 'Old', 'Other')][string[]] $Test1,
[validateSet('New', 'Old', 'Other')][string[]] $Test2
)
}
New-Function -Test1 New -Test2 New,
New-Function -Test1 New, Old -Test2 New
New-Function -Test1 New, Old -Test2 New
In code it will insert junk so it would seem PowerShell issue.
But if you look at the error raised by TabExpansion2
, there's a coercion issue coming from what I assume is your completer script, no?
I think you're reading into it too much. Just check 10 lines of code I've attached. You can reproduce it on those 10 lines. Copy/Paste into Code/ISE and try to autocomplete parameter Test2 with 3 values.
Quick and dirty repro:
$script = @'
function New-Function {
[cmdletBinding()]
param(
[validateSet('New', 'Old', 'Other')][string[]] $Test1,
[validateSet('New', 'Old', 'Other')][string[]] $Test2
)
}
New-Function -Test1 New -Test2
New-Function -Test1 New, Old -Test2 New
New-Function -Test1 New, Old -Test2 New
'@
$cursorColumn = $script.IndexOf('-Test2 ')
TabExpansion2 -inputScript $script -cursorColumn $cursorColumn | % completionmatches
The symptom seems to show up essentially when you have the same function used later on in the script, and then you return to an earlier function call to the same function and start to tab complete it. It reproduces in a completely separate console as well, safe to say it's not the VS Code extension itself.
The completions I get from this are the generic "here's a list of files from the current dir" sort of completions, completely ignoring the validateset results or not finding them for some reason.
Looks like it's down to something in PS. 😞
Should I open it up in PowerShell repo? as it seems PS5.1 / 7.1 as well.
Ah, interesting. Yeah without the complexity of added argument completers, it looks like this is a bug in PowerShell's completion engine (which there are still a number of).
Worth opening an issue in the PowerShell repo.
Would you be able to workaround it in PS 5.1. Otherwise I'm gonna die daily. I've been frustrated so much by this lack of autocompletion thinking that I do something wrong. And if PS team fixes it in PowerShell it will be 7.1 only.
@PrzemyslawKlys in the ISE example you showed, the , character is being used as line continuation. If you look at the syntax highlighting in the ISE you'll see the second line is being treated as input to the first command.
@vexx32 IndexOf
is putting the cursor index at <here>-Test2
Also here's an editor command you can use to test if TabExpansion2
gives the same result:
@SeeminglyScience - well
Nothing shows up on line 8
Would you be able to workaround it in PS 5.1
I'm not sure. Our policy has generally been that the actual completions are the province of PowerShell and PSES just hooks them up. There are a number of cases now where it would be nice to improve on the behaviour though.
I suspect to do it properly, we would need to spin PowerShell's completer library into its own package, ship it with PSES and override TabExpansion2
in PSES on WinPS. I'm not sure how feasible that is, or whether I could convince the people I need to convince that it's worth it.
Well autocomplete is useless for arrays it seems. You can't expect people using autocomplete only on last instance. I often go back to older code and it never works.
As a work around, it seems like if you type an extra , and tab complete before it it works.
e.g. New-Function -Test1 New -Test2 Other,,
> Left Arrow > Tab
Doesn't work for me:
Edit... oh it works
I guess I could use it that way 💯
FYI I updated the editor command above and added a key bind of Ctrl + Shift + Space. Hopefully that makes it a little easier to test this kind of thing.
Also, another work around is adding a pipe, e.g.
# This works, remove the | and it doesn't.
New-Function -Test1 New,<tab> |
somethingelsehere
COol :-D I will be using the comma workaround in near future.
Issue Description
I am experiencing a problem with... completions failing for 2nd entry.
Notice that it works on 14th line, and then very same command fails on line 10th.
I tried to replicate it to give you reproducible code but I just can't. I'm experiencing it across all my modules and I can't pinpoint it to what I'm doing wrong. It fails the same way for both
[Microsoft.GroupPolicy.GPPermissionType[]]
which is an enum, but also have the same issue with ValidateSet and Register-ArgumentCompleter that makes me want to cry :-)Attached Logs
1601583262-5511c227-6bca-4824-9bad-6f29a894ed501601499246405.zip
Follow the instructions in the README about capturing and sending logs.
Environment Information
Visual Studio Code
PowerShell Information
Visual Studio Code Extensions
Visual Studio Code Extensions(Click to Expand)
|Extension|Author|Version| |---|---|---| |better-toml|bungcip|0.3.2| |csharp|ms-dotnettools|1.23.2| |errorlens|usernamehw|3.2.2| |github-linker|gimenete|0.2.3| |gitlens|eamodio|10.2.2| |line-endings|steditor|1.0.3| |LogFileHighlighter|emilast|2.9.0| |markdown-all-in-one|yzhang|3.3.0| |material-icon-theme|PKief|4.3.0| |open-in-browser|techer|2.0.0| |powershell-preview|ms-vscode|2020.9.0| |project-manager|alefragnani|11.3.0| |rainbow-brackets|2gua|0.0.6| |run-in-powershell|tobysmith568|1.1.0| |swdc-vscode|softwaredotcom|2.3.12| |vscode-markdownlint|DavidAnson|0.37.0| |vscode-toggle-quotes|BriteSnow|0.3.3| |vscode-wakatime|WakaTime|4.0.8| |vscode-yaml|redhat|0.11.1| |xml|DotJoshJohnson|2.5.1|