Skip to content

Instantly share code, notes, and snippets.

@KMConner
Created September 22, 2018 15:48
Show Gist options
  • Save KMConner/b1025c84001d4a7bba26b9fce9155cd3 to your computer and use it in GitHub Desktop.
Save KMConner/b1025c84001d4a7bba26b9fce9155cd3 to your computer and use it in GitHub Desktop.
Register-ArgumentCompleter -Native -CommandName git -ScriptBlock {
param([string]$commandName, [string]$wordToComplete, [int]$cursorPosition)
function MatchOnly([string] $cmd, [string[]]$candidate){
$ret = $candidate -like "$cmd*"
if ($ret.Length -eq 0) {
return [System.String]::Empty
} elseif ($ret.Length -eq 1) {
return [System.Management.Automation.CompletionResult]::new($ret[0] + " ")
} else {
$l = [System.Int32]::MaxValue
foreach($r in $ret) {
if ($l -gt $r.Length) {
$l = $r.Length
}
}
[int] $ll = $cmd.Length
:loop while($ll -lt $l) {
foreach ($r in $ret) {
if ($r[$ll] -ne $ret[0][$ll]) {
break loop
}
}
$ll += 1
}
if ($ll -ne $cmd.Length) {
return [System.Management.Automation.CompletionResult]::new($ret[0].Substring(0, $ll))
}
}
}
function CompleteGitCommand {
param([string] $cmd)
[string[]]$gitCommands = @(
"clone", "init", "add", "mv", "reset",
"rm", "bisect", "grep", "log", "show",
"status", "branch", "checkout", "commit", "diff",
"merge", "rebase", "tag", "fetch", "pull",
"push", "clean", "send-email", "am", "shortlog",
"apply", "gui", "range-diff", "archive", "config",
"help", "show-branch", "describe", "reflog", "stage",
"blame", "instaweb", "remote", "stash", "difftool",
"lfs", "repack", "bundle", "replace", "submodule",
"flow", "request-pull", "cherry", "format-patch", "mergetool",
"whatchanged", "cherry-pick", "fsck", "revert", "worktree",
"citool", "gc", "notes")
return MatchOnly $cmd $gitCommands
}
function CompleteHelpCommand ([string] $cmd) {
return CompleteGitCommand $cmd
}
function CompleteCommitCommand ([string] $cmd) {
[string[]] $commitArgument = @(
"--ahead-behind", "--include", "--quiet",
"--all", "--interactive", "--reedit-message=",
"--amend", "--long", "--reset-author",
"--author=", "--message=", "--reuse-message=",
"--branch", "--short", "--no-fixup",
"--cleanup=", "--no-post-rewrite", "--signoff",
"--date=", "--no-verify", "--squash=",
"--dry-run", "--null", "--status",
"--edit", "--only", "--template=",
"--file=", "--patch", "--untracked-files",
"--fixup=", "--porcelain", "--verbose",
"--gpg-sign", "--post-rewrite", "--verify",
"--no-ahead-behind", "--no-gpg-sign", "--no-reedit-message",
"--no-all", "--no-include", "--no-reset-author",
"--no-amend", "--no-interactive", "--no-reuse-message",
"--no-author", "--no-long", "--no-short",
"--no-branch", "--no-message", "--no-signoff",
"--no-cleanup", "--no-null", "--no-squash",
"--no-date", "--no-only", "--no-status",
"--no-dry-run", "--no-patch", "--no-template",
"--no-edit", "--no-porcelain", "--no-untracked-files",
"--no-file", "--no-verbose", "--no-quiet"
)
return MatchOnly $cmd $commitArgument
}
$all = $wordToComplete.Substring(0, $cursorPosition)
$mid = $all.TrimStart()
$mid = $mid.Substring(3, $mid.Length - 3 - $commandName.Length)
$tokens = $all.Split(" ", 3)
if ([System.String]::IsNullOrWhiteSpace($mid)) {
return CompleteGitCommand $commandName
} elseif ($tokens.Length -ge 2) {
$command = $tokens[1]
switch ($command) {
"help" { return CompleteHelpCommand $commandName }
"commit" { return CompleteCommitCommand $commandName }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment