-
Notifications
You must be signed in to change notification settings - Fork 903
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
Tab completion does not work since PowerShell 7.4 #3364
Comments
I can confirm this, after upgrading to PS 7.4 tab completion stopped working and I can't get it working anymore. |
@yan12125 Do you know how to quickly workaround this? I tried to rename all occurrences to |
I downgraded PowerShell. |
I want to have the latest 7.4 version so that's not what I want to do, I can live for some time w/o these completions. It looks like the fix should be easy, I don't see anything that can cause bigger problems, and the code doesn't hardly depend on anything what was remove by the TabExpansion PR. It looks like the problem is how things are exported or something?, but I looked to this only 5mins so I can be wrong. |
I'm not sure if there is an easy fix. PowerShell < 7.4 calls the Scoop has a similar issue (Moeologist/scoop-completion#35), and a relevant fix (Moeologist/scoop-completion#25) is quite large. |
That aren't a good news, it looks like they will need to rewrite it to make it work again, what means we will be some time without tab completion 😞 |
For background information, see PowerShell/PowerShell#20930 (comment) Here's a solution that works in v7.4+:
function script:Get-AliasNames($exe) {
@($exe, "$exe.exe") + @(Get-Alias | Where-Object { $_.Definition -eq $exe } | Select-Object -Exp Name)
}
Register-ArgumentCompleter -Native -CommandName (Get-AliasNames choco) -ScriptBlock {
param($wordToComplete, $commandAst, $cursorColumn)
# NOTE:
# * The stringified form of $commandAst is the command's own command line (irrespective of
# whether other statements are on the same line or whether it is part of a pipeline).
# * However, trailing whitespace is trimmed in the string representation of $commandAst.
# Therefore, when the actual command line ends in space(s), they must be added back
# so that ChocolateyTabExpansion recognizes the start of a new argument.
$ownCommandLine = [string] $commandAst
$ownCommandLine = $ownCommandLine.Substring(0, [Math]::Min($ownCommandLine.Length, $cursorColumn))
$ownCommandLine += ' ' * ($cursorColumn - $ownCommandLine.Length)
ChocolateyTabExpansion $ownCommandLine
} |
I've fixed a problem in the code in the previous comment, which now makes it support intra-line expansions properly too - from what I can tell, this makes it suitable for a fix. However, if you want to avoid having to modify the module, I've posted a polyfill that overrides the |
Thank you very much for the update! I just need one more line in param($wordToComplete, $commandAst, $cursorColumn) Without this, the behavior is kind of different from chocolatey on older PowerShell. When I type |
Ouch! Thank you for catching that, @yan12125 - code in the earlier comment is now updated (I had simply made a copy-paste error when only partially replacing the original code). |
@mklement0 Are you able to submit a PR for the changes that you're making? It sounds like you have it very close to working universally across PS versions. |
… v7.4+ Make export of legacy `TabExpansion` function conditional on the PowerShell version.
… v7.4+ By using the new Register-ArgumentCompleter API TabExpansion is not used since PowerShell 7.4, so the export of legacy `TabExpansion` function is made conditional on the PowerShell version. diff --git a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 index 149bcd08..6c1f164e 100644 --- a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 +++ b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 @@ -264,26 +264,50 @@ if ($PowerTab_RegisterTabExpansion) { return } -if (Test-Path Function:\TabExpansion) { - Rename-Item Function:\TabExpansion TabExpansionBackup -} - -function TabExpansion($line, $lastWord) { - $lastBlock = [System.Text.RegularExpressions.Regex]::Split($line, '[|;]')[-1].TrimStart() +# PowerShell up to v7.3.x: use a custom TabExpansion function. +if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 4)) { + if (Test-Path Function:\TabExpansion) { + Rename-Item Function:\TabExpansion TabExpansionBackup + } - switch -regex ($lastBlock) { - # Execute Chocolatey tab completion for all choco-related commands - "^$(Get-AliasPattern choco) (.*)" { - ChocolateyTabExpansion $lastBlock - } + function TabExpansion($line, $lastWord) { + $lastBlock = [System.Text.RegularExpressions.Regex]::Split($line, '[|;]')[-1].TrimStart() + - # Fall back on existing tab expansion - default { - if (Test-Path Function:\TabExpansionBackup) { - TabExpansionBackup $line $lastWord + switch -regex ($lastBlock) { + # Execute Chocolatey tab completion for all choco-related commands + "^$(Get-AliasPattern choco) (.*)" { + ChocolateyTabExpansion $lastBlock + } + + # Fall back on existing tab expansion + default { + if (Test-Path Function:\TabExpansionBackup) { + TabExpansionBackup $line $lastWord + } } } } +} else { # PowerShell v7.4+: use the Register-ArgumentCompleter cmdlet (PowerShell no longer calls TabExpansion) + function script:Get-AliasNames($exe) { + @($exe) + @(Get-Alias | Where-Object { $_.Definition -eq $exe } | Select-Object -Exp Name) + } + + Register-ArgumentCompleter -Native -CommandName (Get-AliasNames choco) -ScriptBlock { + param($wordToComplete, $commandAst, $cursorColumn) + + # NOTE: + # * The stringified form of $commandAst is the command's own command line (irrespective of + # whether other statements are on the same line or whether it is part of a pipeline). + # * However, trailing whitespace is trimmed in the string representation of $commandAst. + # Therefore, when the actual command line ends in space(s), they must be added back + # so that ChocolateyTabExpansion recognizes the start of a new argument. + $ownCommandLine = [string] $commandAst + $ownCommandLine = $ownCommandLine.Substring(0, [Math]::Min($ownCommandLine.Length, $cursorColumn)) + $ownCommandLine += ' ' * ($cursorColumn - $ownCommandLine.Length) + + ChocolateyTabExpansion $ownCommandLine + } } # SIG # Begin signature block diff --git a/src/chocolatey.resources/helpers/chocolateyProfile.psm1 b/src/chocolatey.resources/helpers/chocolateyProfile.psm1 index a9968117..252d60af 100644 --- a/src/chocolatey.resources/helpers/chocolateyProfile.psm1 +++ b/src/chocolatey.resources/helpers/chocolateyProfile.psm1 @@ -25,7 +25,11 @@ Import-Module "$thisDirectory\Chocolatey.PowerShell.dll" -Cmdlet "Get-Environmen . $thisDirectory\functions\Write-FunctionCallLogMessage.ps1 . $thisDirectory\ChocolateyTabExpansion.ps1 -Export-ModuleMember -Alias refreshenv -Function 'Update-SessionEnvironment', 'TabExpansion' +$funcs = @('Update-SessionEnvironment') +if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 4)) { + $funcs += 'TabExpansion' # Legacy TabExpansion function is only used up to PowerShell v7.3.x +} +Export-ModuleMember -Alias refreshenv -Function $funcs # SIG # Begin signature block # MIInKwYJKoZIhvcNAQcCoIInHDCCJxgCAQExDzANBglghkgBZQMEAgEFADB5Bgor
… v7.4+ By using the new Register-ArgumentCompleter API TabExpansion is not used since PowerShell 7.4, so the export of legacy `TabExpansion` function is made conditional on the PowerShell version.
… v7.4+ By using the new Register-ArgumentCompleter API TabExpansion is not used since PowerShell 7.4, so the export of legacy `TabExpansion` function is made conditional on the PowerShell version.
… v7.4+ By using the new Register-ArgumentCompleter API TabExpansion is not used since PowerShell 7.4, so the export of legacy `TabExpansion` function is made conditional on the PowerShell version.
The newer method is available from v5 and up, so we have no need to wait for v7.4+ to change over. This will also let us remove the fallback earlier, once we no longer support PS <5.0.
… v7.4+ By using the new Register-ArgumentCompleter API TabExpansion is not used since PowerShell 7.4, so the export of legacy `TabExpansion` function is made conditional on the PowerShell version.
The newer method is available from v5 and up, so we have no need to wait for v7.4+ to change over. This will also let us remove the fallback earlier, once we no longer support PS <5.0.
(#3364) Fix broken tab completion (expansion) in PowerShell v7.4+
These tests are verifying the old method and are targeting an implementation detail, rather than actually checking the tab completion results, which the following tests do anyway. As such, we're best off skipping them as there is no direct way to check the same things for the Register-ArgumentCompleter method. The tests for the tab completion results themselves covers this adequately already.
These tests are verifying the old method and are targeting an implementation detail, rather than actually checking the tab completion results, which the following tests do anyway. As such, we're best off removingthem as there is no direct way to check the same things for the Register-ArgumentCompleter method. The tests for the tab completion results themselves covers this adequately already.
These tests are verifying the old method and are targeting an implementation detail, rather than actually checking the tab completion results, which the following tests do anyway. As such, we're best off removing them as there is no direct way to check the same things for the Register-ArgumentCompleter method. The tests for the tab completion results themselves cover this adequately already.
(#3364) Remove unusable tab completion tests
Checklist
What You Are Seeing?
Hitting tab after typing
choco
only shows filenamesWhat is Expected?
Choco commands like
install
,upgrade
, etc. should be shownHow Did You Get This To Happen?
choco
and hit tabSystem Details
0 packages installed.
Installed Packages
Output Log
(N/A - not sure how to get logs for tab completion)
Additional Context
The cause is that Chocolatey only defines
TabExpansion
function to enable completions, while that function is no longer used by PowerShell 7.4 [1]. A solution might be addingTabExpansion2
function (supported since PowerShell 3) besides the existingTabExpansion
function, so that all users with PowerShell 2 ~ 7.4 can have Chocolatey tab completions.As a side note, if
TabExpansion2
is added, #2255 will likely be solved as well.[1] PowerShell/PowerShell#18337
The text was updated successfully, but these errors were encountered: