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*"
}