-
-
Notifications
You must be signed in to change notification settings - Fork 814
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
PowerShell Alias Tab Completion not working #852
Comments
Right now, the module peeks at the definition of the proxy function - # The regular expression here is roughly follows this pattern:
#
# <begin anchor><whitespace>*<git>(<whitespace><parameter>)*<whitespace>+<$args><whitespace>*<end anchor>
#
# The delimiters inside the parameter list and between some of the elements are non-newline whitespace characters ([^\S\r\n]).
# In those instances, newlines are only allowed if they preceded by a non-newline whitespace character.
#
# Begin anchor (^|[;`n])
# Whitespace (\s*)
# Git Command (?<cmd>$(GetAliasPattern git))
# Parameters (?<params>(([^\S\r\n]|[^\S\r\n]``\r?\n)+\S+)*)
# $args Anchor (([^\S\r\n]|[^\S\r\n]``\r?\n)+\`$args)
# Whitespace (\s|``\r?\n)*
# End Anchor ($|[|;`n])
$script:GitProxyFunctionRegex = "(^|[;`n])(\s*)(?<cmd>$(Get-AliasPattern git))(?<params>(([^\S\r\n]|[^\S\r\n]``\r?\n)+\S+)*)(([^\S\r\n]|[^\S\r\n]``\r?\n)+\`$args)(\s|``\r?\n)*($|[|;`n])" Also, to enable this feature make sure you're importing with |
Looking at the RegEx it makes a call to $(Get-AliasPattern git) function Get-AliasPattern($cmd) {
$aliases = @($cmd) + @(Get-Alias | Where-Object { $_.Definition -eq $cmd } | Select-Object -Exp Name)
"($($aliases -join '|'))"
} Then that in turn makes a call to I'm guessing it should return a list of Alias Definitions created for git commands. I my case running Get-Alias | Where-Object { $_.Definition -eq $cmd } | Select-Object -Exp Name returns nothing. If I run Get-Alias | Where-Object { $_.Definition -Like "Git-*" } | Select-Object -Exp Name Then I get a list of all my git Aliases as I've prefixed all the Alias function names with |
This: $aliases = @($cmd) + @(Get-Alias | Where-Object { $_.Definition -eq $cmd } | Select-Object -Exp Name) Is looking for aliases of the specified The problem is that the proxy regex is not matching your function definition. If you do something like this, it would work: function Git-Checkout { git checkout $args }
Set-Alias -Name gco -Value Git-Checkout -Option AllScope -Force
Import-Module posh-git -arg 0,0,1 |
I've added a new alias to my list of aliases for regex testing purposes as suggested above: function Git-Checkout2 { git checkout $args }
Set-Alias -Name gcko -Value Git-Checkout2 -Option AllScope -Force I'm also setting the arguments when importing the module: # Setup Git Posh with arguments
# [bool]$ForcePoshGitPrompt,
# [bool]$UseLegacyTabExpansion,
# [bool]$EnableProxyFunctionExpansion
Import-Module posh-git -arg 0,0,1 When I type My full list of aliases looks like this: $git = "git"
$defaultRemote = "origin"
$defaultBranch = "master"
function Execute-Git-Command {
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$True,
Position=1
)]
[String]
$GitCommand
)
Write-Host "Command:" -NoNewline -ForegroundColor Magenta
Write-Host "$GitCommand" -ForegroundColor Cyan
Invoke-Expression "$GitCommand"
}
function Get-Current-Branch {
$currentBranch = Invoke-Expression "$git rev-parse --abbrev-ref HEAD"
return $currentBranch
}
function Git-Add-Remote-Upstream
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$UpstreamUrl
)
if(-not($PSBoundParameters.ContainsKey('UpstreamUrl'))) {
Get-Help Git-Add-Remote-Upstream
return
}
& Execute-Git-Command -GitCommand "$git remote add upstream $UpstreamUrl"
}
Set-Alias -Name garu -Value Git-Add-Remote-Upstream -Option AllScope -Force
function Git-Checkout
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$BranchName
)
if(-not($PSBoundParameters.ContainsKey('BranchName'))) {
Get-Help Git-Checkout
return
}
& Execute-Git-Command -GitCommand "$git checkout $BranchName"
}
Set-Alias -Name gco -Value Git-Checkout -Option AllScope -Force
function Git-Checkout2 { git checkout $args }
Set-Alias -Name gcko -Value Git-Checkout2 -Option AllScope -Force
function Git-Commit
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$CommitMessage
)
if(-not($PSBoundParameters.ContainsKey('CommitMessage'))) {
Get-Help Git-Commit
return
}
& Execute-Git-Command -GitCommand "$git commit -m ""$CommitMessage"""
}
Set-Alias -Name gcm -Value Git-Commit -Option AllScope -Force
function Git-Commit-Push
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$CommitMessage
)
if(-not($PSBoundParameters.ContainsKey('CommitMessage'))) {
Get-Help Git-Commit-Push
return
}
$currentBranch = Get-Current-Branch
& Git-Commit -CommitMessage $CommitMessage
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $currentBranch
& Git-Status
}
Set-Alias -Name gcmp -Value Git-Commit-Push -Option AllScope -Force
function Git-Delete-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$BranchName
)
if(-not($PSBoundParameters.ContainsKey('BranchName'))) {
Get-Help Git-Delete-Branch
return
}
& Git-Delete-Remote-Branch -BranchName $BranchName
& Git-Delete-Local-Branch -BranchName $BranchName
}
Set-Alias -Name gdb -Value Git-Delete-Branch -Option AllScope -Force
function Git-Delete-Local-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$BranchName
)
if(-not($PSBoundParameters.ContainsKey('BranchName'))) {
Get-Help Git-Delete-Local-Branch
return
}
& Git-Checkout -BranchName $defaultBranch
& Execute-Git-Command -GitCommand "$git branch -d $BranchName"
}
Set-Alias -Name gdlb -Value Git-Delete-Local-Branch -Option AllScope -Force
function Git-Delete-Remote-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$BranchName
)
if(-not($PSBoundParameters.ContainsKey('BranchName'))) {
Get-Help Git-Delete-Remote-Branch
return
}
& Git-Checkout -BranchName $defaultBranch
& Execute-Git-Command -GitCommand "$git push -d $defaultRemote $BranchName"
}
Set-Alias -Name gdrb -Value Git-Delete-Remote-Branch -Option AllScope -Force
function Git-Fetch
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git fetch"
}
Set-Alias -Name gf -Value Git-Fetch -Option AllScope -Force
function Git-Help
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$Alias
)
if(-not($PSBoundParameters.ContainsKey('Alias'))) {
Get-Help Git-Help
return
}
& Get-Help $Alias
}
Set-Alias -Name gh -Value Git-Help -Option AllScope -Force
function Git-List-Aliases
{
[CmdletBinding()]
PARAM (
)
& Get-Alias -Definition Git-* | Select-Object -Property Name, Definition, Description
}
Set-Alias -Name gla -Value Git-List-Aliases -Option AllScope -Force
function Git-List-Local-Branches
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git branch"
}
Set-Alias -Name gllb -Value Git-List-Local-Branches -Option AllScope -Force
function Git-List-Pending-Commits
{
[CmdletBinding()]
PARAM (
)
$currentBranch = Get-Current-Branch
& Execute-Git-Command -GitCommand "$git log --pretty=oneline $defaultRemote/$currentBranch..HEAD"
}
Set-Alias -Name glpc -Value Git-List-Pending-Commits -Option AllScope -Force
function Git-List-Remotes
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git remote -v"
}
Set-Alias -Name glr -Value Git-List-Remotes -Option AllScope -Force
function Git-List-Remote-Branches
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git branch -a"
}
Set-Alias -Name glrb -Value Git-List-Remote-Branches -Option AllScope -Force
function Git-List-Stashes
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git stash list"
}
Set-Alias -Name gls -Value Git-List-Stashes -Option AllScope -Force
function Git-Merge-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch')) -or -not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Merge-Branch
return
}
& Git-Checkout -BranchName $SourceBranch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $SourceBranch
& Git-Checkout -BranchName $TargetBranch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $TargetBranch
& Execute-Git-Command -GitCommand "$git merge $SourceBranch"
}
Set-Alias -Name gmb -Value Git-Merge-Branch -Option AllScope -Force
function Git-Merge-Branch-Push
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch')) -or -not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Merge-Branch-Push
return
}
& Git-Merge-Branch -SourceBranch $SourceBranch -TargetBranch $TargetBranch
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $TargetBranch
& Git-Status
}
Set-Alias -Name gmbp -Value Git-Merge-Branch-Push -Option AllScope -Force
function Git-Merge-Current-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Merge-Current-Branch
return
}
$currentBranch = Get-Current-Branch
& Git-Merge-Branch -SourceBranch $currentBranch -TargetBranch $TargetBranch
}
Set-Alias -Name gmcb -Value Git-Merge-Current-Branch -Option AllScope -Force
function Git-Merge-Current-Branch-Push
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Merge-Current-Branch-Push
return
}
$currentBranch = Get-Current-Branch
& Git-Merge-Branch -SourceBranch $currentBranch -TargetBranch $TargetBranch
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $TargetBranch
& Git-Status
}
Set-Alias -Name gmcbp -Value Git-Merge-Current-Branch-Push -Option AllScope -Force
function Git-New-Branch-From-Current-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$BranchName
)
if(-not($PSBoundParameters.ContainsKey('BranchName'))) {
Get-Help Git-New-Branch-From-Current-Branch
return
}
$currentBranch = Get-Current-Branch
& Git-Checkout -BranchName $currentBranch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $currentBranch
& Execute-Git-Command -GitCommand "$git branch $BranchName"
& Execute-Git-Command -GitCommand "$git push --set-upstream $defaultRemote $BranchName"
& Git-Checkout -BranchName $BranchName
}
Set-Alias -Name gnbfc -Value Git-New-Branch-From-Current-Branch -Option AllScope -Force
function Git-Pull
{
[CmdletBinding()]
PARAM (
)
$currentBranch = Get-Current-Branch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $currentBranch
}
Set-Alias -Name gp -Value Git-Pull -Option AllScope -Force
function Git-Pull-Verbose
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$Remote,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$SourceBranch
)
if(-not($PSBoundParameters.ContainsKey('Remote')) -or -not($PSBoundParameters.ContainsKey('SourceBranch'))) {
Get-Help Git-Pull-Verbose
return
}
& Execute-Git-Command -GitCommand "$git pull $Remote $SourceBranch"
}
Set-Alias -Name gpv -Value Git-Pull-Verbose -Option AllScope -Force
function Git-Push
{
[CmdletBinding()]
PARAM (
)
$currentBranch = Get-Current-Branch
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $currentBranch
}
Set-Alias -Name gpush -Value Git-Push -Option AllScope -Force
function Git-Push-Verbose
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$Remote,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('Remote')) -or -not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Push-Verbose
return
}
& Execute-Git-Command -GitCommand "$git push $Remote $TargetBranch"
}
Set-Alias -Name gpushv -Value Git-Push-Verbose -Option AllScope -Force
function Git-Rebase-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch')) -or -not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Rebase-Branch
return
}
& Git-Checkout -BranchName $SourceBranch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $SourceBranch
& Git-Checkout -BranchName $TargetBranch
& Git-Pull-Verbose -Remote $defaultRemote -SourceBranch $TargetBranch
& Execute-Git-Command -GitCommand "$git rebase $SourceBranch"
}
Set-Alias -Name grb -Value Git-Rebase-Branch -Option AllScope -Force
function Git-Rebase-Branch-Push
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$TargetBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch')) -or -not($PSBoundParameters.ContainsKey('TargetBranch'))) {
Get-Help Git-Rebase-Branch-Push
return
}
& Git-Rebase-Branch -SourceBranch $SourceBranch -TargetBranch $TargetBranch
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $TargetBranch
& Git-Status
}
Set-Alias -Name grbp -Value Git-Rebase-Branch-Push -Option AllScope -Force
function Git-Rebase-Current-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch'))) {
Get-Help Git-Rebase-Current-Branch
return
}
$currentBranch = Get-Current-Branch
& Git-Rebase-Branch -SourceBranch $SourceBranch -TargetBranch $currentBranch
}
Set-Alias -Name grcb -Value Git-Rebase-Current-Branch -Option AllScope -Force
function Git-Rebase-Current-Branch-Push
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$SourceBranch
)
if(-not($PSBoundParameters.ContainsKey('SourceBranch'))) {
Get-Help Git-Rebase-Current-Branch-Push
return
}
$currentBranch = Get-Current-Branch
& Git-Rebase-Branch -SourceBranch $SourceBranch -TargetBranch $currentBranch
& Git-Push-Verbose -Remote $defaultRemote -TargetBranch $currentBranch
& Git-Status
}
Set-Alias -Name grcbp -Value Git-Rebase-Current-Branch-Push -Option AllScope -Force
function Git-Status
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git status"
}
Set-Alias -Name gs -Value Git-Status -Option ReadOnly -Force -Description "git status"
function Git-Rename-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$OldBranch,
[Parameter(
Mandatory=$False,
Position=2
)]
[String]
$NewBranch
)
if(-not($PSBoundParameters.ContainsKey('OldBranch')) -or -not($PSBoundParameters.ContainsKey('NewBranch'))) {
Get-Help Git-Rename-Branch
return
}
& Execute-Git-Command -GitCommand "$git branch -m $OldBranch $NewBranch"
& Execute-Git-Command -GitCommand "$git push $defaultRemote :$OldBranch"
& Execute-Git-Command -GitCommand "$git push --set-upstream $defaultRemote $NewBranch"
}
Set-Alias -Name grnb -Value Git-Rename-Branch -Option AllScope -Force
function Git-Rename-Current-Branch
{
[CmdletBinding()]
PARAM (
[Parameter(
Mandatory=$False,
Position=1
)]
[String]
$NewBranch
)
if(-not($PSBoundParameters.ContainsKey('NewBranch'))) {
Get-Help Git-Rename-Current-Branch
return
}
$currentBranch = Get-Current-Branch
& Git-Rename-Branch -OldBranch $currentBranch -NewBranch $NewBranch
}
Set-Alias -Name grncb -Value Git-Rename-Current-Branch -Option AllScope -Force
function Git-Undo-All-Changes
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git stash push -u"
& Execute-Git-Command -GitCommand "$git stash drop"
}
Set-Alias -Name guc -Value Git-Undo-All-Changes -Option AllScope -Force -Description "Undo all local changes"
function Git-Update
{
[CmdletBinding()]
PARAM (
)
& Execute-Git-Command -GitCommand "$git update-git-for-windows"
}
Set-Alias -Name gupd -Value Git-Update -Option AllScope -Force -Description "Undo all local changes" |
I have tried doing exactly the same as you but when I hit N.B. I have created a I get the same result when running PowerShell git.aliases.mp4 |
Try |
Even correcting my typo and using |
Well, I’m not sure what the deal is there, but I did find that my config was importing |
@Aankhen Configure the alias without an extension and configure the alias before importing posh-git and it works: |
There are two issues here being conflated a bit. Simple PowerShell alias tab expansion works but there is a bug where if you specify an alias with an extension e.g. The second issue is around the use of "proxy functions" e.g. |
For what it’s worth, I use |
I must check that I am setting the aliases before I call Import-Module posh-git -arg 0,0,1 I agree it's brittle to rely on a RegEx expression to parse the custom aliases as everyone will create them slightly differently like I have with not using Would be safer if there was some way of decorating the "proxy functions" to inform the tab completion what each function/parameter does and then provide the correct completion info. |
Yes, that is what I was suggesting above in the "second issue". But I don't know what the feasibility is for this approach. |
Yes it does seem very brittle. By decorate function parameters, do you mean creating some attributes which Posh-Git scans for? # autocomplete all git checkout arguments
Register-GitArgumentCompleter -Function Git-Checkout -Command checkout
# autocomplete the branch parameter of the Git-Checkout function as a git branch
Register-GitArgumentCompleter -Function Git-Checkout -Parameter branch -Type branch Wouldn't this be fairly simple to implement as it could just call into the existing autocompleter? |
Is there any update on this? |
I was experiencing this issue and found that the cause was the order of the alias getting set and the module being imported. # Does not work
Import-Module posh-git
Set-Alias -Name g -Value git
# Works!
Set-Alias -Name g -Value git
Import-Module posh-git |
System Details
1.0.0 {userPath}\Documents\PowerShell\Modules\posh-git\1.0.0
7.1.3
hosted in Windows Terminal version:1.6.10571.0
2.29.2.windows.2
Microsoft Windows NT 10.0.19042.0
Issue Description
I have just updated my existing
posh-git
installation to version1.0.0
, hoping to take advantage of pull request #779 which added the tab completion feature to PowerShell aliases.Unfortunately it hasn't worked or not as I had expected it would have work.
For example I have created a PowerShell alias called
gco
forgit checkout
I had expected that when I typed
gco m
and then pressed thetab
key that the tab completion would have cycled through a suggested list of git branch names beginning with the letterm
every time thetab
key was pressed.What actually happens in the above scenario is nothing after pressing the tab key the command
gco m
remains unchanged.Do I need to do anything else to enable PowerShell aliases to have tab completion functionality?
The text was updated successfully, but these errors were encountered: