Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tab expansion support for git restore / switch #702

Merged
merged 3 commits into from
Oct 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/GitParamTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ $shortGitParams = @{
rebase = 'm s X S q v n C f i p x'
remote = 'v'
reset = 'q p'
restore = 's p W S q m'
revert = 'e m n S s X'
rm = 'f n r q'
shortlog = 'n s e w'
stash = 'p k u a q'
status = 's b u z'
submodule = 'q b f n N'
switch = 'c C d f m q t'
tag = 'a s u f d v n l m F'
whatchanged = 'p'
}
Expand Down Expand Up @@ -70,13 +72,15 @@ $longGitParams = @{
reflog = 'stale-fix expire= expire-unreachable= all updateref rewrite verbose'
remote = 'verbose'
reset = 'patch quiet soft mixed hard merge keep'
restore = 'source= patch worktree staged quiet progress no-progress ours theirs merge conflict= ignore-unmerged ignore-skip-worktree-bits overlay no-overlay'
revert = 'edit mainline no-edit no-commit gpg-sign signoff strategy= strategy-option continue quit abort'
rm = 'force dry-run cached ignore-unmatch quiet'
shortlog = 'numbered summary email format='
show = 'pretty= format= abbrev-commit no-abbrev-commit oneline encoding= notes no-notes show-notes no-standard-notes standard-notes show-signature'
stash = 'patch no-keep-index keep-index include-untracked all quiet index'
status = 'short branch porcelain long untracked-files ignore-submodules ignored column no-column'
submodule = 'quiet branch force cached files summary-limit remote no-fetch checkout merge rebase init name reference recursive depth'
switch = 'create force-create detach guess no-guess force discard-changes merge conflict= quiet no-progress track no-track orphan ignore-other-worktrees recurse-submodules no-recurse-submodules'
tag = 'annotate sign local-user force delete verify list sort column no-column contains points-at message file cleanup'
whatchanged = 'since'
}
Expand Down Expand Up @@ -173,6 +177,14 @@ $gitParamValues = @{
rebase = @{
strategy = 'resolve recursive octopus ours subtree'
}
restore = @{
conflict = 'merge diff3'
source = {
param($ref)
gitBranches $matches['ref'] $true
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't always review code, but when I do it's six months later. 💪

Did you mean to use $ref here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, good catch. I'll submit a PR shortly.

gitTags $matches['ref']
}
}
revert = @{
strategy = 'resolve recursive octopus ours subtree'
}
Expand All @@ -185,4 +197,7 @@ $gitParamValues = @{
'untracked-files' = 'no normal all'
'ignore-submodules' = 'none untracked dirty all'
}
switch = @{
conflict = 'merge diff3'
}
}
47 changes: 37 additions & 10 deletions src/GitTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ function script:gitCmdOperations($commands, $command, $filter) {
$script:someCommands = @('add','am','annotate','archive','bisect','blame','branch','bundle','checkout','cherry',
'cherry-pick','citool','clean','clone','commit','config','describe','diff','difftool','fetch',
'format-patch','gc','grep','gui','help','init','instaweb','log','merge','mergetool','mv',
'notes','prune','pull','push','rebase','reflog','remote','rerere','reset','revert','rm',
'shortlog','show','stash','status','submodule','svn','tag','whatchanged', 'worktree')
'notes','prune','pull','push','rebase','reflog','remote','rerere','reset','restore','revert','rm',
'shortlog','show','stash','status','submodule','svn','switch','tag','whatchanged', 'worktree')

if ((($PSVersionTable.PSVersion.Major -eq 5) -or $IsWindows) -and ($script:GitVersion -ge [System.Version]'2.16.2')) {
$script:someCommands += 'update-git-for-windows'
Expand Down Expand Up @@ -190,6 +190,10 @@ function script:gitCheckoutFiles($GitStatus, $filter) {
gitFiles $filter (@($GitStatus.Working.Unmerged) + @($GitStatus.Working.Modified) + @($GitStatus.Working.Deleted))
}

function script:gitDeleted($GitStatus, $filter) {
gitFiles $filter $GitStatus.Working.Deleted
}

function script:gitDiffFiles($GitStatus, $filter, $staged) {
if ($staged) {
gitFiles $filter $GitStatus.Index.Modified
Expand All @@ -203,8 +207,13 @@ function script:gitMergeFiles($GitStatus, $filter) {
gitFiles $filter $GitStatus.Working.Unmerged
}

function script:gitDeleted($GitStatus, $filter) {
gitFiles $filter $GitStatus.Working.Deleted
function script:gitRestoreFiles($GitStatus, $filter, $staged) {
if ($staged) {
gitFiles $filter (@($GitStatus.Index.Added) + @($GitStatus.Index.Modified) + @($GitStatus.Index.Deleted))
}
else {
gitFiles $filter (@($GitStatus.Working.Unmerged) + @($GitStatus.Working.Modified) + @($GitStatus.Working.Deleted))
}
}

function script:gitAliases($filter) {
Expand Down Expand Up @@ -249,10 +258,16 @@ function script:expandShortParams($hash, $cmd, $filter) {
}

function script:expandParamValues($cmd, $param, $filter) {
$gitParamValues[$cmd][$param].Trim() -split ' ' |
Where-Object { $_ -like "$filter*" } |
Sort-Object |
ForEach-Object { -join ("--", $param, "=", $_) }
$paramValues = $gitParamValues[$cmd][$param]

$completions = if ($paramValues -is [scriptblock]) {
& $paramValues $filter | Where-Object { $_ -like "$filter*" }
}
else {
$paramValues.Trim() -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object
}

$completions | ForEach-Object { -join ("--", $param, "=", $_) }
}

function Expand-GitCommand($Command) {
Expand Down Expand Up @@ -373,6 +388,18 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {
gitCheckoutFiles $GitStatus $matches['files']
}

# Handles git restore -s <ref> - must come before the next regex case
"^restore.* (?-i)-s\s*(?<ref>\S*)$" {
gitBranches $matches['ref'] $true
gitTags $matches['ref']
break
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if more of these switch cases should be using break. Once we've found a "match" do we need to continue with every subsequent regex match?

Copy link

@pinkfloydx33 pinkfloydx33 Sep 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually running into issues with this case myself and ended up matching --staged somehow, and kinda gave up and forgot to look back at it. That said, I think this looks semi-correct. I think this will match "-S" (which is the short-form of staged) followed by anything since we aren't using a case-sensitive match

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkeithhill re: break ... when working on my version of this as well as #696 I realized that the fall through would end up matching some of the later cases per the regex, but then return nothing based on the inner function calls. (lots of Write-Host debugging :-p) and was going to suggest we throw in breaks. With that said, I swear I encountered at least one instance where the fall-through actually caught an edge-case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I swear I encountered at least one instance where the fall-through actually caught an edge-case.

That's why I'm nervous about throwing in break everywhere. But in this new case, it should break IMO.

RE the above code matching on -S, good catch. I'll make this regex be case-sensitive.

}

# Handles git restore <path>
"^restore(?:.* (?<staged>(?:(?-i)-S|--staged))|.*) (?<files>\S*)$" {
gitRestoreFiles $GitStatus $matches['files'] $matches['staged']
}

# Handles git rm <path>
"^rm.* (?<index>\S*)$" {
gitDeleted $GitStatus $matches['index']
Expand All @@ -388,8 +415,8 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {
gitMergeFiles $GitStatus $matches['files']
}

# Handles git checkout <ref>
"^(?:checkout).* (?<ref>\S*)$" {
# Handles git checkout|switch <ref>
"^(?:checkout|switch).* (?<ref>\S*)$" {
& {
gitBranches $matches['ref'] $true
gitRemoteUniqueBranches $matches['ref']
Expand Down
11 changes: 11 additions & 0 deletions test/TabExpansion.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@ Describe 'TabExpansion Tests' {
}
}

Context 'Restore Source Branch TabExpansion Tests' {
It 'Tab completes source branches -s' {
$result = & $module GitTabExpansionInternal 'git restore -s mas'
$result | Should BeExactly 'master'
}
It 'Tab completes source branches --source=' {
$result = & $module GitTabExpansionInternal 'git restore --source=mas'
$result | Should BeExactly '--source=master'
}
}

Context 'Vsts' {
BeforeEach {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')]
Expand Down