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+)+)?)?"

function Register-GitCompletion {
  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*"
  }
}

Export-ModuleMember -Function Register-GitCompletion