pwsh-git-completion.psm1
# Yes this will probably break in older/newer git versions than the one this is written for. $githelpParseRegex = "(?<= {4})(-{1,2}(?:\w+)(?:(?:-\w+)+)?)(?:, )?(-{1,2}(?:\w+)(?:(?:-\w+)+)?)?" Register-ArgumentCompleter -Native -CommandName git -ScriptBlock { param($wordToComplete, $commandAst, $cursorPosition) $ast = $commandAst.ToString() $words = $ast -split '\s+' $command = $words | Select-Object -Index 1 $result = Invoke-Command -ScriptBlock { if ($ast -match "^git add") { $addableFiles = @(git ls-files --others --exclude-standard -m) $alreadyAddedFiles = @($words | Select-Object -Skip 2) $addableFiles | Where-Object { $_ -notIn $alreadyAddedFiles } } elseif ($ast -match "^git rm") { $removableFiles = git ls-files $removableFiles } elseif ($ast -match "^git restore") { $restorableFiles = git ls-files -m $restorableFiles } elseif ($ast -match "^git (checkout|rebase)") { $switchableBranches = git branch -a --format "%(refname:lstrip=2)" $switchableBranches } elseif ($ast -match "^git switch") { $switchableBranches = ` @(git branch --format "%(refname:lstrip=2)") ` + @(git branch -r --format "%(refname:lstrip=3)") $switchableBranches } else { $gitCommands = (git --list-cmds=main,others,alias,nohelpers) if (!$gitCommands.Contains($command)) { $gitCommands } else { "" } } } if ($wordToComplete -match "^-" -and $command) { # omg, a monstrosity # also 2>&1 since apparently some `git <command> -h` writes to stderr ¯\_(ツ)_/¯ $flags = (git $command -h 2>&1 | Select-String -Pattern $githelpParseRegex).Matches | ForEach-Object { $_.Groups | Where-Object { $_.Success -and $_.Name -ne 0 } } | ForEach-Object { $_.Value } $result = @($result) + @($flags) } $result = @($result) $result -like "*$wordToComplete*" } |