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

Adds support for tab-completion of all parameters, long and short #395

Merged
merged 26 commits into from
Feb 6, 2017
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2f4af9f
tab completion for branch and log parameters implemented
seamlessintegrations Apr 12, 2015
1ad85e2
tab completion for add and status parameters implemented
seamlessintegrations Apr 12, 2015
021afc4
tab completion for diff and merge parameters implemented
seamlessintegrations Apr 12, 2015
53ddd27
parameter values completion added for add, branch, diff, log, merge, …
seamlessintegrations Apr 12, 2015
3c97e14
added support for short parameters for add, branch, diff, log, merge,…
seamlessintegrations Apr 12, 2015
98b0b9f
added tab completion for commit cmd
seamlessintegrations Apr 12, 2015
8a6a99d
added tab completion for checkout, fetch, pull, push cmds
seamlessintegrations Apr 12, 2015
57c9159
added tab completion for rebase
seamlessintegrations Apr 12, 2015
f990b3b
added tab completion for all other cmds except bisect, svn
seamlessintegrations Apr 15, 2015
f40922a
added tab completion for bisect
seamlessintegrations Feb 2, 2017
df39d27
Merge branch 'master' of https://github.com/dahlbyk/posh-git
seamlessintegrations Feb 2, 2017
c76f1f6
moved file due to new filesystem layout
seamlessintegrations Feb 2, 2017
fc39c00
moved source params expansion statement into posh-git.psm1
seamlessintegrations Feb 2, 2017
4361b1b
replaced aliases with full cmdlet names
seamlessintegrations Feb 2, 2017
bf2bda9
whitespaces / eol / eof fixes
seamlessintegrations Feb 2, 2017
0302fd5
eol at eof added
seamlessintegrations Feb 2, 2017
fe0608e
renamed file for consistency reasons
seamlessintegrations Feb 2, 2017
dffdbd3
renamed file for consistency reasons
seamlessintegrations Feb 2, 2017
8eff9cc
added parameter tab expansion tests
seamlessintegrations Feb 2, 2017
f11d033
corrected test result expectations
seamlessintegrations Feb 2, 2017
a96f23c
renamed file for consistency reasons
seamlessintegrations Feb 3, 2017
302f50e
Clean up PR issues that @dahlbyk raised.
rkeithhill Feb 4, 2017
48a1062
closing braces are on a new line now
seamlessintegrations Feb 4, 2017
51a78d0
command lists are now precomputed
seamlessintegrations Feb 6, 2017
5083dcd
merged both versions
seamlessintegrations Feb 6, 2017
703f328
Merge branch 'rkeithhill-rkeithhill/fix-last-misc-pr-issues'
seamlessintegrations Feb 6, 2017
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
36 changes: 36 additions & 0 deletions src/GitTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,27 @@ function script:expandGitAlias($cmd, $rest) {
}
}

function script:expandParams($cmd, $filter) {
$params[$cmd] -split ' ' |
Where-Object { $_ -like "$filter*" } |
Sort-Object |
ForEach-Object { -join ("--", $_) }
}

function script:expandShortParams($cmd, $filter) {
$shortparams[$cmd] -split ' ' |
Where-Object { $_ -like "$filter*" } |
Sort-Object |
ForEach-Object { -join ("-", $_) }
}

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

function GitTabExpansion($lastBlock) {
$res = Invoke-Utf8ConsoleCommand { GitTabExpansionInternal $lastBlock }
$res
Expand Down Expand Up @@ -330,6 +351,21 @@ function GitTabExpansionInternal($lastBlock) {
gitBranches $matches['ref'] $true
gitTags $matches['ref']
}

# Handles git <cmd> --<param>=<value>
"^(?<cmd>$($someCommands -join '|')).* --(?<param>[^=]+)=(?<value>\S*)$" {
Copy link
Owner

Choose a reason for hiding this comment

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

I'm not terribly concerned about performance, but can we precompute $someCommands -join '|' since it's used a couple times?

More generally, It seems a little curious to use $someCommands here rather than explicitly looking for the keys in $paramvalues (or $params/$shortparams). Does everything still work as expected if a command is found in $someCommands but not one of the params lists? If not, we might consider a test to iterate over $someCommands (via tab-completing git <tab>) checking if long and short parameters can be completed successfully.

expandParamValues $matches['cmd'] $matches['param'] $matches['value']
}

# Handles git <cmd> --<param>
"^(?<cmd>$($someCommands -join '|')).* --(?<param>\S*)$" {
expandParams $matches['cmd'] $matches['param']
}

# Handles git <cmd> -<shortparam>
"^(?<cmd>$($someCommands -join '|')).* -(?<shortparam>\S*)$" {
expandShortParams $matches['cmd'] $matches['shortparam']
}
}
}

Expand Down
143 changes: 143 additions & 0 deletions src/ParamsExpansions.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
$shortparams = @{
add = 'n v f i p e u A N'
bisect = ''
blame = 'b L l t S p M C h c f n s e w'
branch = 'd D l f m M r a v vv q t u'
checkout = 'q f b B t l m p'
cherry = 'v'
'cherry-pick' = 'e x r m n s S X'
clean = 'd f i n q e x X'
clone = 'l s q v n o b u c'
commit = 'a p C c z F m t s n e i o u v q S'
config = 'f l z e'
diff = 'p u s U z B M C D l S G O R a b w W'
difftool = 'd y t x g'
fetch = 'a f k p n t u q v'
grep = 'a i I w v h H E G P F n l L O z c p C A B W f e q'
help = 'a g i m w'
init = 'q'
log = 'L n i E F g c c m r t'
merge = 'e n s X q v S m'
mergetool = 't y'
mv = 'f k n v'
notes = 'f m F C c n s q v'
prune = 'n v'
pull = 'q v e n s X r a f k u'
push = 'n f u q v'
rebase = 'm s X S q v n C f i p x'
remote = 'v'
reset = 'q p'
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'
tag = 'a s u f d v n l m F'
whatchanged = 'p'
}

$params = @{
add = 'dry-run verbose force interactive patch edit update all no-ignore-removal no-all ignore-removal intent-to-add refresh ignore-errors ignore-missing'
bisect = 'no-checkout term-old term-new'
blame = 'root show-stats reverse porcelain line-porcelain incremental encoding= contents date score-debug show-name show-number show-email abbrev'
branch = 'color no-color list abbrev= no-abbrev column no-column merged no-merged contains set-upstream track no-track set-upstream-to= unset-upstream edit-description delete create-reflog force move all verbose quiet'
checkout = 'quiet force ours theirs track no-track detach orphan ignore-skip-worktree-bits merge conflict= patch'
'cherry-pick' = 'edit mainline no-commit signoff gpg-sign ff allow-empty allow-empty-message keep-redundant-commits strategy= strategy-option= ´continue quit abort'
clean = 'force interactive dry-run quiet exclude='
clone = 'local no-hardlinks shared reference quiet verbose progress no-checkout bare mirror origin branch upload-pack template= config depth single-branch no-single-branch recursive recurse-submodules separate-git-dir='
commit = 'all patch reuse-message reedit-message fixup squash reset-author short branch porcelain long null file author date message template signoff no-verify allow-empty allow-empty-message cleanup= edit no-edit ammend no-post-rewrite include only untracked-files verbose quiet dry-run status no-status gpg-sign no-gpg-sign'
config = 'replace-all add get get-all get-regexp get-urlmatch global system local file blob remove-section rename-section unset unset-all list bool int bool-or-int path null get-colorbool get-color edit includes no-includes'
describe = 'dirty all tags contains abbrev candidates= exact-match debug long match always first-parent'
diff = 'patch no-patch unified= raw patch-with-raw minimal patience histogram diff-algorithm= stat numstat shortstat dirstat summary patch-with-stat name-only name-status submodule color no-color word-diff word-diff-regex color-words no-renames check full-index binary apprev break-rewrites find-renames find-copies find-copies-harder irreversible-delete diff-filter= pickaxe-all pickaxe-regex relative text ignore-space-at-eol ignore-space-change ignore-all-space ignore-blank-lines inter-hunk-context= function-context exit-code quiet ext-diff no-ext-diff textconv no-textconv ignore-submodules src-prefix dst-prefix no-prefix'
difftool = 'dir-diff no-prompt prompt tool= tool-help no-symlinks symlinks extcmd= gui'
fetch = 'all append depth= unshallow update-shallow dry-run force keep multiple prune no-tags tags recurse-submodules= no-recurse-submodules submodule-prefix= recurse-submodules-default= update-head-ok upload-pack quiet verbose progress'
gc = 'aggressive auto prune= no-prune quiet force'
grep = 'cached no-index untracked no-exclude-standard exclude-standard text textconv no-textconv ignore-case max-depth word-regexp invert-match full-name extended-regexp basic-regexp perl-regexp fixed-strings line-number files-with-matches open-file-in-pager null count color no-color break heading show-function context after-context before-context function-context and or not all-match quiet'
help = 'all guides info man web'
init = 'quiet bare template= separate-git-dir= shared='
log = 'follow no-decorate decorate source use-mailmap full-diff log-size max-count skip since after until before author committer grep-reflog grep all-match regexp-ignore-case basic-regexp extended-regexp fixed-strings perl-regexp remove-empty merges no-merges min-parents max-parents no-min-parents no-max-parents first-parent not all branches tags remote glob= exclude= ignore-missing bisect stdin cherry-mark cherry-pick left-only right-only cherry walk-reflogs merge boundary simplify-by-decoration full-history dense sparse simplify-merges ancestry-path date-order author-date-order topo-order reverse objects objects-edge unpacked no-walk= do-walk pretty format= abbrev-commit no-abbrev-commit oneline encoding= notes no-notes standard-notes no-standard-notes show-signature relative-date date= parents children left-right graph show-linear-break '
merge = 'commit no-commit edit no-edit ff no-ff ff-only log no-log stat no-stat squash no-squash strategy strategy-option verify-signatures no-verify-signatures summary no-summary quiet verbose progress no-progress gpg-sign rerere-autoupdate no-rerere-autoupdate abort'
mergetool = 'tool= tool-help no-prompt prompt'
mv = 'force dry-run verbose'
notes = 'force message file reuse-message reedit-message ref ignore-missing stdin dry-run strategy= commit abort quiet verbose'
prune = 'dry-run verbose expire'
pull = 'quiet verbose recurse-submodules= no-recurse-submodules= commit no-commit edit no-edit ff no-ff ff-only log no-log stat no-stat squash no-squash strategy= strategy-option= verify-signatures no-verify-signatures summary no-summary rebase= no-rebase all append depth= unshallow update-shallow force keep no-tags update-head-ok upload-pack progress'
push = 'all prune mirror dry-run porcelain delete tags follow-tags receive-pack= exec= force-with-lease= no-force-with-lease force repo= set-upstream thin no-thin quiet verbose progress recurse-submodules= verify no-verify'
rebase = 'onto continue abort keep-empty skip edit-todo merge strategy= strategy-option= gpg-sign quiet verbose stat no-stat no-verify verify force-rebase fork-point no-fork-point ignore-whitespace whitespace= committer-date-is-author-date ignore-date interactive preserve-merges exec root autosquash no-autosquash autostash no-autostash no-ff'
reflog = 'stale-fix expire= expire-unreachable= all updateref rewrite verbose'
remote = 'verbose'
reset = 'patch quiet soft mixed hard merge keep'
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'
tag = 'annotate sign local-user force delete verify list sort column no-column contains points-at message file cleanup'
whatchanged = 'since'
}

$paramvalues = @{
blame = @{
encoding = 'utf-8 none' }
branch = @{
color = 'always never auto'
abbrev = '7 8 9 10' }
checkout = @{
conflict = 'merge diff3' }
'cherry-pick' = @{
strategy = 'resolve recursive octopus ours subtree' }
commit = @{
'cleanup' = 'strip whitespace verbatim scissors default' }
diff = @{
unified = '0 1 2 3 4 5'
'diff-algorithm' = 'default patience minimal histogram myers'
color = 'always never auto'
'word-diff' = 'color plain porcelain none'
abbrev = '7 8 9 10'
'diff-filter' = 'A C D M R T U X B *'
'inter-hunk-context' = '0 1 2 3 4 5'
'ignore-submodules' = 'none untracked dirty all' }
difftool = @{
tool = 'vimdiff vimdiff2 araxis bc3 codecompare deltawalker diffmerge diffuse ecmerge emerge gvimdiff gvimdiff2 kdiff3 kompare meld opendiff p4merge tkdiff xxdiff' }
fetch = @{
'recurse-submodules' = 'yes on-demand no'
'recurse-submodules-default' = 'yes on-demand' }
init = @{
shared = 'false true umask group all world everybody o' }
log = @{
decorate = 'short full no'
'no-walk' = 'sorted unsorted'
pretty = 'oneline short medium full fuller email raw'
format = 'oneline short medium full fuller email raw'
encoding = 'UTF-8'
date = 'relative local default iso rfc short raw' }
merge = @{
strategy = 'resolve recursive octopus ours subtree'
log = '1 2 3 4 5 6 7 8 9' }
mergetool = @{
tool = 'vimdiff vimdiff2 araxis bc3 codecompare deltawalker diffmerge diffuse ecmerge emerge gvimdiff gvimdiff2 kdiff3 kompare meld opendiff p4merge tkdiff xxdiff' }
notes = @{
strategy = 'manual ours theirs union cat_sort_uniq' }
pull = @{
strategy = 'resolve recursive octopus ours subtree'
'recurse-submodules' = 'yes on-demand no'
'no-recurse-submodules' = 'yes on-demand no'
rebase = 'false true preserve' }
push = @{
'recurse-submodules' = 'check on-demand' }
rebase = @{
strategy = 'resolve recursive octopus ours subtree' }
revert = @{
strategy = 'resolve recursive octopus ours subtree' }
show = @{
pretty = 'oneline short medium full fuller email raw'
format = 'oneline short medium full fuller email raw'
encoding = 'utf-8' }
status = @{
'untracked-files' = 'no normal all'
'ignore-submodules' = 'none untracked dirty all' }
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL at EOF please. We have a .editorconfig file that will handle this if you use an editor that works with EditorConfig files. For instance, Visual Studio Code.


1 change: 1 addition & 0 deletions src/posh-git.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ if ($psv.Major -lt 3 -and !$NoVersionWarn) {
. $PSScriptRoot\GitUtils.ps1
. $PSScriptRoot\GitPrompt.ps1
. $PSScriptRoot\GitTabExpansion.ps1
. $PSScriptRoot\ParamsExpansions.ps1
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about renaming this file to GitParamTabExpansion.ps1 (no need for the s on Params or Expansions). I think that would be consistent with most of the other scripts. Thanks!

. $PSScriptRoot\TortoiseGit.ps1

if (!$Env:HOME) { $Env:HOME = "$Env:HOMEDRIVE$Env:HOMEPATH" }
Expand Down