Skip to content
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

Open
5 tasks done
yan12125 opened this issue Nov 30, 2023 · 12 comments · May be fixed by #3387
Open
5 tasks done

Tab completion does not work since PowerShell 7.4 #3364

yan12125 opened this issue Nov 30, 2023 · 12 comments · May be fixed by #3387

Comments

@yan12125
Copy link

yan12125 commented Nov 30, 2023

Checklist

  • I have verified this is the correct repository for opening this issue.
  • I have verified no other issues exist related to my problem.
  • I have verified this is not an issue for a specific package.
  • I have verified this issue is not security related.
  • I confirm I am using official, and not unofficial, or modified, Chocolatey products.

What You Are Seeing?

Hitting tab after typing choco only shows filenames

What is Expected?

Choco commands like install, upgrade, etc. should be shown

How Did You Get This To Happen?

  1. Make sure PowerShell profile contains the following snippet
$ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
if (Test-Path($ChocolateyProfile)) {
  Import-Module "$ChocolateyProfile"
}
  1. Upgrade PowerShell to 7.4.0
  2. Type choco and hit tab

System Details

  • Operating System: 10.0.19045.0
  • Windows PowerShell version:
Name                           Value
----                           -----
PSVersion                      7.4.0
PSEdition                      Core
GitCommitId                    7.4.0
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
  • Chocolatey CLI Version: 2.2.2
  • Chocolatey Licensed Extension version: N/A - 0 packages installed.
  • Chocolatey License type: Open Source
  • Terminal/Emulator: PowerShell Core 7.4.0 on Microsoft Terminal 1.18.3181.0

Installed Packages

au 2022.10.24
chocolatey 2.2.2
chocolatey-compatibility.extension 1.0.0
chocolatey-core.extension 1.4.0
chocolatey-windowsupdate.extension 1.0.5
dellcommandupdate 5.1.0
delta 0.16.5
DotNet4.6.1 4.6.1055.20170308
Firefox 120.0.0
git.install 2.43.0
gnupg 2.4.3
KB2919355 1.0.20160915
KB2919442 1.0.20160915
KB2999226 1.0.20181019
KB3033929 1.0.5
KB3035131 1.0.3
KB3118401 1.0.5
kdeconnect-kde 23.4.0
keepassxc 2.7.6
libreoffice-still 7.5.8
microsoft-windows-terminal 1.18.3181
miktex.install 23.10.12
neovim 0.9.4
nodejs-lts 20.10.0
notepadplusplus.install 8.6.0
PIME 1.3.0
powershell-core 7.4.0
python39 3.9.13.20230703
ripgrep 13.0.0.20220913
syncthingtray 1.4.9
synergy 1.14.6.19
texstudio.install 4.6.3
vcredist140 14.38.33130
vcredist2015 14.0.24215.20170201

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 adding TabExpansion2 function (supported since PowerShell 3) besides the existing TabExpansion 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

@silverqx
Copy link

silverqx commented Dec 5, 2023

I can confirm this, after upgrading to PS 7.4 tab completion stopped working and I can't get it working anymore.

@silverqx
Copy link

silverqx commented Dec 6, 2023

@yan12125 Do you know how to quickly workaround this? I tried to rename all occurrences to TabExpansion2 but it didn't help, is even possible to quickly workaround it?

@yan12125
Copy link
Author

yan12125 commented Dec 6, 2023

Do you know how to quickly workaround this?

I downgraded PowerShell.

@silverqx
Copy link

silverqx commented Dec 6, 2023

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.

@yan12125
Copy link
Author

yan12125 commented Jan 5, 2024

I'm not sure if there is an easy fix. PowerShell < 7.4 calls the TabExpansion function provided by Chocolatey for custom tab completions, and that function is no longer called by PowerShell > 7.4 as indicated in the aforementionef PR. A proper fix is probably using newer completion APIs like Register-ArgumentCompleter.

Scoop has a similar issue (Moeologist/scoop-completion#35), and a relevant fix (Moeologist/scoop-completion#25) is quite large.

@silverqx
Copy link

silverqx commented Jan 5, 2024

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 😞

@mklement0
Copy link

mklement0 commented Jan 17, 2024

For background information, see PowerShell/PowerShell#20930 (comment)

Here's a solution that works in v7.4+:

  • For those looking to apply an immediate fix, they can apply it as follows:

    • Open the relevant file for editing:

      Invoke-Item "$env:ChocolateyInstall\helpers\ChocolateyTabExpansion.ps1"
      
    • Paste the code below at the end, save, and then start a new session.

      • Caveat: Since this obviously breaks the signature of said file, this will only work if your script-execution policy is set to not require local scripts to be signed.
  • To fix the problem at the source:

    • Add the code below to https://github.com/chocolatey/choco/blob/develop/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1

    • If PowerShell versions prior to Windows PowerShell v5.1 do not need to be supported anymore:

      • Remove the following, then-obsolete code:
        • if (Test-Path Function:\TabExpansion) {
          Rename-Item Function:\TabExpansion TabExpansionBackup
          }
          function TabExpansion($line, $lastWord) {
          $lastBlock = [System.Text.RegularExpressions.Regex]::Split($line, '[|;]')[-1].TrimStart()
          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
          }
          }
          }
          }
    • If pre-v5.1 support is still needed:

      • Enclose the following code in if ($PSVersionTable.PSVersion -ge '7.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
}

@mklement0
Copy link

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 TabExpansion2 function only, and, if added to $PROFILE, should work with all modules that still rely on the legacy TabExpansion function - see PowerShell/PowerShell#20930 (comment)

@yan12125
Copy link
Author

Thank you very much for the update! I just need one more line in Register-ArgumentCompleter script block to make it work: (the line removed during a comment edit)

    param($wordToComplete, $commandAst, $cursorColumn)

Without this, the behavior is kind of different from chocolatey on older PowerShell. When I type choco out and hit the Tab key, an older PowerShell shows the complete subcommand choco outdated, while the Register-ArgumentCompleter approach shows choco --help.

@mklement0
Copy link

mklement0 commented Jan 19, 2024

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).

@pauby
Copy link
Member

pauby commented Jan 19, 2024

@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.

mklement0 added a commit to mklement0/choco that referenced this issue Jan 19, 2024
@mklement0
Copy link

@pauby, I've submitted #3387 - hope that's good enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants