@@ -70,6 +70,59 @@ function Convert-ToPowerShellBranchCompletionText {
7070 return $BranchName
7171}
7272
73+ function Get-GitLongOptionCompletions {
74+ param (
75+ [Parameter (Mandatory = $true )]
76+ [string ]$SubCommand ,
77+ [Parameter (Mandatory = $true )]
78+ [string ]$WordToComplete
79+ )
80+
81+ if (-not $WordToComplete.StartsWith (' -' )) {
82+ return @ ()
83+ }
84+
85+ try {
86+ $helpText = git $SubCommand - h 2>&1 | Out-String
87+ if (-not $helpText ) { return @ () }
88+
89+ $rawTokens = [regex ]::Matches($helpText , ' --[^\s,]+' ) |
90+ ForEach-Object { $_.Value } |
91+ Sort-Object - Unique
92+
93+ $expanded = foreach ($token in $rawTokens ) {
94+ $clean = $token.Trim ().TrimEnd(' ,' , ' ;' )
95+ $clean = $clean -replace ' <.*$' , ' '
96+
97+ if ($clean -match ' ^--\[no-\](.+)$' ) {
98+ $suffix = $matches [1 ] -replace ' \[.*$' , ' '
99+ if ($suffix ) {
100+ " --$suffix "
101+ " --no-$suffix "
102+ }
103+ continue
104+ }
105+
106+ $clean = $clean -replace ' \[.*$' , ' '
107+ if ($clean.StartsWith (' --' )) {
108+ $clean
109+ }
110+ }
111+
112+ $options = $expanded |
113+ Sort-Object - Unique |
114+ Where-Object { $_ -like " $WordToComplete *" }
115+
116+ if (-not $options ) { return @ () }
117+
118+ return $options | ForEach-Object {
119+ [System.Management.Automation.CompletionResult ]::new($_ , $_ , ' ParameterName' , $_ )
120+ }
121+ } catch {
122+ return @ ()
123+ }
124+ }
125+
73126
74127# --- Custom Git Command Functions ---
75128function UpMerge {
@@ -353,12 +406,21 @@ function Register-GitAliasCompletion {
353406 if ($gitCursorPosition -lt 0 ) { $gitCursorPosition = 0 }
354407 if ($gitCursorPosition -gt $gitLine.Length ) { $gitCursorPosition = $gitLine.Length }
355408
356- # Use posh-git's official completion function
357- if (Get-Command GitTabExpansion - ErrorAction SilentlyContinue) {
358- try {
359- $results = GitTabExpansion $gitLine $gitCursorPosition
409+ # Delegate to native completion for `git <subcommand> ...`.
410+ # This preserves completion for long options (e.g. --track, --detach)
411+ # and other git-specific argument completion behavior.
412+ try {
413+ $nativeCompletion = [System.Management.Automation.CommandCompletion ]::CompleteInput(
414+ $gitLine ,
415+ $gitCursorPosition ,
416+ $null
417+ )
418+ if ($null -ne $nativeCompletion -and
419+ $null -ne $nativeCompletion.CompletionMatches -and
420+ $nativeCompletion.CompletionMatches.Count -gt 0 ) {
421+ $delegateMatches = @ ($nativeCompletion.CompletionMatches )
360422 if ($subCommand -in @ (' checkout' , ' switch' , ' merge' , ' rebase' , ' branch' , ' reset' , ' revert' )) {
361- return $results | ForEach-Object {
423+ $delegateMatches = @ ( $nativeCompletion .CompletionMatches | ForEach-Object {
362424 if ($null -eq $_ ) { return }
363425 $completionText = $_.CompletionText
364426 if ($completionText -is [string ] -and $completionText.StartsWith (' #' )) {
@@ -372,16 +434,40 @@ function Register-GitAliasCompletion {
372434 }
373435
374436 return $_
437+ })
438+ }
439+
440+ if ($wordToComplete -like ' -*' ) {
441+ $optionCompletions = Get-GitLongOptionCompletions - SubCommand $subCommand - WordToComplete $wordToComplete
442+ if ($optionCompletions -and $optionCompletions.Count -gt 0 ) {
443+ $combined = @ ()
444+ $seen = @ {}
445+ foreach ($item in @ ($delegateMatches + $optionCompletions )) {
446+ if ($null -eq $item ) { continue }
447+ $key = $item.CompletionText
448+ if (-not $seen.ContainsKey ($key )) {
449+ $combined += $item
450+ $seen [$key ] = $true
451+ }
452+ }
453+
454+ return $combined
375455 }
376456 }
377457
378- return $results
379- } catch {
380- Write-Warning " posh-git's GitTabExpansion failed for alias '$commandName '."
458+ return $delegateMatches
381459 }
460+ } catch {
461+ Write-Warning " Native completion delegation failed for alias '$commandName '."
462+ }
463+
464+ # Long option fallback when native completion isn't available.
465+ $optionCompletions = Get-GitLongOptionCompletions - SubCommand $subCommand - WordToComplete $wordToComplete
466+ if ($optionCompletions -and $optionCompletions.Count -gt 0 ) {
467+ return $optionCompletions
382468 }
383469
384- # Fallback if posh-git isn't loaded or its function fails
470+ # Final fallback when delegated completion is unavailable
385471 if ($subCommand -in @ (' checkout' , ' switch' , ' merge' , ' rebase' , ' branch' , ' reset' , ' revert' )) {
386472 try {
387473 $branches = git branch - a -- format= ' %(refname:short)' |
0 commit comments