Closed scrouthtv closed 4 years ago
Your expectation is correct. That should work and works for me.
Has this ever worked for you (so a regression)? Or is this the first time you're trying?
Could you attempt to <TAB>
complete again with an imported command and then send me a few things?
gcm git, grep, ls
$WslCompletionFunctions
wsl -l
wsl apt list bash-completion
I just installed the module and it didn't work out of the box. Output:
PS C:\Users\x> gcm git, grep, ls
CommandType Name Version Source
----------- ---- ------- ------
Function git 0.2.2 WslInterop
Function grep 0.2.2 WslInterop
Function ls 0.2.2 WslInterop
PS C:\Users\x> $WslCompletionFunctions
Name Value
---- -----
git _minimal
grep _minimal
PS C:\Users\x> wsl -l
Windows Subsystem for Linux Distributions:
Arch (Default)
PS C:\Users\x> wsl apt list bash-completion
zsh:1: command not found: apt
PS C:\Users\x> wsl pacman -Qi bash-completion
Name : bash-completion
Version : 2.10-1
Description : Programmable completion for the bash shell
Architecture : any
URL : https://github.com/scop/bash-completion
Licenses : GPL2
Groups : None
Provides : None
Depends On : bash
Optional Deps : None
Required By : None
Optional For : bash
Conflicts With : None
Replaces : None
Installed Size : 836.42 KiB
Packager : Bartłomiej Piotrowski <bpiotrowski@archlinux.org>
Build Date : Thu 12 Dec 2019 09:54:58 PM CET
Install Date : Tue 14 Apr 2020 02:45:57 PM CEST
Install Reason : Explicitly installed
Install Script : No
Validated By : Signature
I'm using z shell
if that's causing the trouble.
Thanks. Different distros are typically what complicates things. I recently updated the README to indicate the bash-completion
package was a prerequisite, since not all distributions include it out of the box.
Based on the Install Date and Install Reason for the bash-completion
package, it looks like you just installed it?
Have you tried argument completion again since installing that package?
With the bash-completion
package installed, can you try $WslCompletionFunctions = @{ git = '__git_wrap__git_main'; grep = '_longopt'; ls = '_longopt' }
and then <TAB>
completing again?
Actually I think my system time is messed up. I install bash-completion
before I ran Import-WslCommand
. Since then, I tried completion although it did not work.
However, by running your command, everything works fine:
PS C:\Users\x> Import-WslCommand "git", "grep", "ls"
PS C:\Users\x> gcm git, grep, ls
CommandType Name Version Source
----------- ---- ------- ------
Function git 0.2.2 WslInterop
Function grep 0.2.2 WslInterop
Function ls 0.2.2 WslInterop
PS C:\Users\x> $WslCompletionFunctions = @{ git = '__git_wrap__git_main'; grep = '_longopt'; ls = '_longopt' }
PS C:\Users\x> $WslCompletionFunctions
Name Value
---- -----
ls _longopt
git __git_wrap__git_main
grep _longopt
PS C:\Users\x> git add^C
PS C:\Users\x> grep --after-context=^C
PS C:\Users\x> ls --all^C
I am currently trying completion with bash
as my default shell, but give me two more minutes for a result.
I somehow managed to get
less -<TAB>--------------------------------------------------c^C
Nope, even with bash
as my default shell tab completion is not imported.
PS C:\Users\x> wsl sh -c "env | grep SHELL"
SHELL=/bin/bash
PS C:\Users\x> gcm git
Get-Command: The term 'git' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
PS C:\Users\x> Import-WslCommand "git"
PS C:\Users\x> git <TAB>.bash_profile
Ok. Based on your original output from $WslCompletionFunctions
, I'd recommend also resetting the completion function cache, since it may have been populated from attempts to autocomplete before the bash-completion
package was installed.
ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions"
git
, grep
, and ls
$WslCompletionFunctions
Let me know how it goes. The fact that you were able to autocomplete when $WslCompletionFunctions
was populated correctly indicates there may be an issue with how this is populated.
If there is something I should capture in the README to better support z shell, I would like to figure out what that is and add it.
Doesn't look too good:
PS C:\Users\x> wsl sh -c "env | grep SHELL"
SHELL=/bin/bash
PS C:\Users\x> ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions"
PS C:\Users\x> Import-WslCommand "git", "grep", "ls"
PS C:\Users\x> echo $WslCompletionFunctions
PS C:\Users\x>
I always tried these with a new instance of pwsh. Profile is completely empyt too.
https://pastebin.com/W3f3xdum
These are the files bash-completion
provides on Arch, if there is anything missing.
I guess you retrieve the completion function using
# Try to find the completion function.
$global:WslCompletionFunctions[$command] = wsl.exe (". /usr/share/bash-completion/bash_completion 2> /dev/null; __load_completion $command 2> /dev/null; complete -p $command 2> /dev/null | sed -E 's/^complete.*-F ([^ ]+).*`$/\1/'" -split ' ')
# If we can't find a completion function, default to _minimal which will resolve Linux file paths.
if ($null -eq $global:WslCompletionFunctions[$command] -or $global:WslCompletionFunctions[$command] -like "complete*") {
$global:WslCompletionFunctions[$command] = "_minimal"
}
# Update the bash completion function cache.
New-Item $WslCompletionFunctionsCache -Force | Out-Null
$global:WslCompletionFunctions | Export-Clixml $WslCompletionFunctionsCache
(WslInterop.psm1
, 3a5c1b7
, line 123 - 135)
When I only run the very first wsl command, it works how (I guess) it is supposed to:
PS C:\Users\x> $command="grep"
PS C:\Users\x> echo $command
grep
PS C:\Users\x> wsl.exe (". /usr/share/bash-completion/bash_completion 2> /dev/null; __load_completion $command 2> /dev/null; complete -p $command 2> /dev/null | sed -E 's/^complete.*-F ([^ ]+).*`$/\1/'" -split ' ')
_longopt
PS C:\Users\x>
Both ls
and git
are also correctly reported.
Can you run through my steps exactly as I shared them?
You should restart PowerShell after clearing the APPDATA cache. Then you also need to attempt autocompletion before calling $WslCompletionFunctions
, otherwise no output would be expected.
Doesn't look too good:
PS C:\Users\x> wsl sh -c "env | grep SHELL" SHELL=/bin/bash PS C:\Users\x> ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions" PS C:\Users\x> Import-WslCommand "git", "grep", "ls" PS C:\Users\x> echo $WslCompletionFunctions PS C:\Users\x>
I always tried these with a new instance of pwsh. Profile is completely empyt too.
I don't see you attempting to <TAB>
complete between importing the commands and outputting $WslCompletionFunctions
.
Oh sorry, my bad. Now the fun begins: I tried this with bash
as in above:
PS C:\Users\x> wsl sh -c "env | grep SHELL"
SHELL=/bin/bash
PS C:\Users\x> ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions"
Remove-Item: Cannot find path 'C:\Users\x\AppData\Roaming\PowerShell WSL Interop\WslCompletionFunctions' because it does not exist.
PS C:\Users\x> Import-WslCommand "git", "grep", "ls"
PS C:\Users\x> git <TAB>add^C
PS C:\Users\x> echo $WslCompletionFunctions
Name Value
---- -----
git __git_wrap__git_main
PS C:\Users\x>
However, with zsh
:
PS C:\Users\x> wsl sh -c "env | grep SHELL"
SHELL=/usr/bin/zsh
PS C:\Users\x> ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions"
Remove-Item: Cannot find path 'C:\Users\x\AppData\Roaming\PowerShell WSL Interop\WslCompletionFunctions' because it does not exist.
PS C:\Users\x> Import-WslCommand "git", "grep", "ls"
PS C:\Users\x> git <TAB>.\.bash_history^C
PS C:\Users\x> echo $WslCompletionFunctions
Name Value
---- -----
git _minimal
PS C:\Users\x>
This is because bash
has a command __load_completion
which is used to retrieve the completion for a given $command
. However, zsh
does not have this command:
> __load_completion grep
zsh: command not found: __load_completion
Ok. Thanks. So sounds like at least bash is working as expected now.
So __load_completion
is defined within /usr/share/bash-completion/bash_completion
which I dot source to identify completion functions, as you saw in the code.
Is there a different way to source this file for z shell so __load_completion
would be defined?
Suggestion:
Change WslInterop.psm1
line 125 to
wsl.exe bash -c ". /usr/share/bash-completion/bash_completion 2> /dev/null; __load_completion $command 2> /dev/null; complete -p $command 2> /dev/null | sed -E 's/^complete.*-F ([^ ]+).*`$/\1/'" -split ' '
For example:
PS C:\Users\x> wsl sh -c "env | grep SHELL"
PS C:\Users\x> $command="grep"
PS C:\Users\x> wsl.exe (". /usr/share/bash-completion/bash_completion 2> /dev/null; __load_completion $command 2> /dev/null; complete -p $command 2> /dev/null | sed -E 's/^complete.*-F ([^ ]+).*`$/\1/'" -split ' ')
PS C:\Users\x> wsl.exe bash -c ". /usr/share/bash-completion/bash_completion 2> /dev/null; __load_completion $command 2> /dev/null; complete -p $command 2> /dev/null | sed -E 's/^complete.*-F ([^ ]+).*`$/\1/'" -split ' '
_longopt
PS C:\Users\x>
I don't really know how sourcing a bash
completion function would work in zsh
so using bash
instead seems to be the easiest (and fastest) way.
I can try that.
Actually I think my system time is messed up. I install
bash-completion
before I ranImport-WslCommand
. Since then, I tried completion although it did not work.However, by running your command, everything works fine:
PS C:\Users\x> Import-WslCommand "git", "grep", "ls" PS C:\Users\x> gcm git, grep, ls CommandType Name Version Source ----------- ---- ------- ------ Function git 0.2.2 WslInterop Function grep 0.2.2 WslInterop Function ls 0.2.2 WslInterop PS C:\Users\x> $WslCompletionFunctions = @{ git = '__git_wrap__git_main'; grep = '_longopt'; ls = '_longopt' } PS C:\Users\x> $WslCompletionFunctions Name Value ---- ----- ls _longopt git __git_wrap__git_main grep _longopt PS C:\Users\x> git add^C PS C:\Users\x> grep --after-context=^C PS C:\Users\x> ls --all^C
I am currently trying completion with
bash
as my default shell, but give me two more minutes for a result.
Can you confirm here that you were using z shell when you set $WslCompletionFunctions = @{ git = '__git_wrap__git_main'; grep = '_longopt'; ls = '_longopt' }
manually and autocompletion worked?
I want to make sure that, assuming $WslCompletionFunctions
is populated correctly, autocompletion would in fact work with z shell.
Sorry for not answering your question. In the retried the test you mentioned with z shell and even with $WslCompletionFunctions
set, completion does not work:
PS C:\Users\x> wsl sh -c "env | grep SHELL"
SHELL=/usr/bin/zsh
PS C:\Users\x> Import-WslCommand "git", "grep", "ls"
PS C:\Users\x> git .\.android\^C
PS C:\Users\x> $WslCompletionFunctions = @{ git = '__git_wrap__git_main'; grep = '_longopt'; ls = '_longopt' }
PS C:\Users\x> $WslCompletionFunctions
Name Value
---- -----
git __git_wrap__git_main
ls _longopt
grep _longopt
PS C:\Users\x> git .\.bash_history^C
PS C:\Users\x> grep --<TAB>^C
PS C:\Users\x> ls --<TAB>^C
I guess there is a second command that converts the __git_wrap__git_main
and _longopt
at runtime to actual completions based on the context at runtime? This function involves wsl too but is not explicitly calling bash
?
Thanks. It not working is what I would have expected given the dot sourcing issue, which is why I was surprised that it might have worked for you looking back at the history of the repros.
Calling bash explicitly both when identifying completion functions and generating completions is the right approach. Now I'm just battling with WSL not accepting the completion generation command when I switch to bash -c
.
@scrouthtv could you try your repro again with the latest code?
ri "$Env:APPDATA\PowerShell WSL Interop\WslCompletionFunctions"
<PATH>
Import-Module "<PATH>\WslInterop.psd1" -Force
Everything works for me now with zsh set as my default shell.
Yep works for me now, too. Thanks for your quick help!
Awesome. 0.2.3 was published with the fix. Thanks for reporting this.
If I'm not mistaken, the readme claims that by importing a wsl command both command and argument completion is enabled automatically for pwsh as well:
To Reproduce Steps to reproduce the behavior:
pwsh
:https://aka.ms/powershell Type 'help' to get help.
PS C:\Users\x> pwsh --version PowerShell 7.0.0
[x@DESKTOP-04NUF17 ~]$ echo $0 bash [x@DESKTOP-04NUF17 ~]$ git
add blame cherry-pick config format-patch gui log.cmd pull remote restore show status worktree
am branch citool describe fsck help merge push repack revert show-branch submodule
apply bundle clean diff gc init mergetool range-diff replace rm sparse-checkout switch
archive checkout clone difftool gitk instaweb mv rebase request-pull send-email stage tag
bisect cherry commit fetch grep log notes reflog reset shortlog stash whatchanged
[x@DESKTOP-04NUF17 ~]$ grep --
--after-context= --byte-offset --dereference-recursive --exclude-from= --fixed-strings --invert-match --max-count= --null-data --regexp=
--basic-regexp --color --devices= --extended-regexp --help --label= --no-filename --only-matching --text
--before-context= --colour --directories= --file= --ignore-case --line-buffered --no-ignore-case --perl-regexp --version
--binary --context= --exclude= --files-with-matches --include= --line-number --no-messages --quiet --with-filename
--binary-files= --count --exclude-dir= --files-without-match --initial-tab --line-regexp --null --recursive --word-regexp
[lenni@DESKTOP-04NUF17 ~]$ ls --
--all --dereference-command-line-symlink-to-dir --hide-control-chars --numeric-uid-gid --tabsize=
--almost-all --directory --human-readable --quote-name --time
--author --dired --hyperlink --quoting-style= --time=
--block-size= --escape --ignore= --recursive --time-style=
--classify --file-type --ignore-backups --reverse --version
--color --format= --indicator-style= --show-control-chars --width=
--color= --full-time --inode --si
--context --group-directories-first --kibibytes --size
--dereference --help --literal --sort
--dereference-command-line --hide= --no-group --sort=
PS C:\Users\x> Import-WslCommand "git", "grep", "ls" PS C:\Users\x>
PS C:\Users\x> git ..bash_profile^C
PS C:\Users\x> grep --^C
PS C:\Users\x> ls --^C
PS C:\Users\x>