zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: update git completion
@ 2017-11-13 20:37 Oliver Kiddle
  2017-11-14 12:29 ` Daniel Shahaf
  0 siblings, 1 reply; 2+ messages in thread
From: Oliver Kiddle @ 2017-11-13 20:37 UTC (permalink / raw)
  To: Zsh workers

This brings git option completion up to 2.15.

I also checked for other changes. git relink has gone at some point and
git interpret-trailers was added. In the past, for custom formats, you
needed git log --format=format:%... Now you can skip the format: part.

Completion for git tag/for-each-ref sort keys and formats is also
improved.

Oliver

diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 10707b454..9ee2eba76 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -293,9 +293,8 @@ _git-branch () {
 
   l='--color --no-color -r --remotes -a -v --verbose --abbrev --no-abbrev --list --points-at --sort'
   c='-l --create-reflog -f --force -t --track --no-track -u --set-upstream --set-upstream-to --unset-upstream --contains --no-contains --merged --no-merged'
-  m='-m --move -M'
+  m='-c --copy -C -m --move -M --edit-description'
   d='-d --delete -D'
-  e='--edit-description'
 
   declare -a dependent_creation_args
   if (( words[(I)(-r|--remotes)] == 0 )); then
@@ -325,37 +324,39 @@ _git-branch () {
   fi
 
   _arguments -S -s \
-    "($c $m $d $e --no-color :)--color=-[turn on branch coloring]:: :__git_color_whens" \
-    "($c $m $d $e : --color)--no-color[turn off branch coloring]" \
-    "($c $m $d $e --no-column)"'--column=[display tag listing in columns]:column.branch option:((always\:"always show in columns" never\:"never show in columns" auto\:"show in columns if the output is to the terminal" column\:"fill columns before rows (default)" row\:"fill rows before columns" plain\:"show in one column" dense\:"make unequal size columns to utilize more space" nodense\:"make equal size columns"))' \
-    "($c $m $d $e --column)"'--no-column[do not display in columns]' \
-    "($c $m $d $e )*--list[list only branches matching glob]:pattern" \
-    "($c $m    $e  -a)"{-r,--remotes}'[list or delete only remote-tracking branches]' \
-    "($c $m $d $e: -r --remotes)-a[list both remote-tracking branches and local branches]" \
-    "($c $m $d $e : -v -vv --verbose)"{-v,-vv,--verbose}'[show SHA1 and commit subject line for each head]' \
-    "($c $m $d $e :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \
-    "($c $m $d $e :)--no-abbrev[do not abbreviate sha1s]" \
-    "($l $m $d $e)"{-l,--create-reflog}"[create the branch's reflog]" \
-    "($l $m $d $e -f --force)"{-f,--force}"[force the creation of a new branch]" \
-    "($l $m $d $e -t --track)"{-t,--track}"[set up configuration so that pull merges from the start point]" \
-    "($l $m $d $e)--no-track[override the branch.autosetupmerge configuration variable]" \
-    "($l $m $d $e -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}"[set up configuration so that pull merges]:remote-branches:__git_remote_branch_names" \
-    "($l $m $d $e -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \
-    "($l $m $d $e)*--contains=[only list branches that contain the specified commit]: :__git_committishs" \
-    "($l $m $d $e)*--no-contains=[only list branches that don't contain the specified commit]: :__git_committishs" \
-    "($l $m $d $e)--merged=[only list branches that are fully contained by HEAD]: :__git_committishs" \
-    "($l $m $d $e)--no-merged=[don't list branches that are fully contained by HEAD]: :__git_committishs" \
+    "($c $m $d --no-color :)--color=-[turn on branch coloring]:: :__git_color_whens" \
+    "($c $m $d : --color)--no-color[turn off branch coloring]" \
+    "($c $m $d --no-column)"'--column=[display tag listing in columns]:column.branch option:((always\:"always show in columns" never\:"never show in columns" auto\:"show in columns if the output is to the terminal" column\:"fill columns before rows (default)" row\:"fill rows before columns" plain\:"show in one column" dense\:"make unequal size columns to utilize more space" nodense\:"make equal size columns"))' \
+    "($c $m $d --column)--no-column[don't display in columns]" \
+    "($c $m $d )*--list[list only branches matching glob]:pattern" \
+    "($c $m     -a)"{-r,--remotes}'[list or delete only remote-tracking branches]' \
+    "($c $m $d : -r --remotes)-a[list both remote-tracking branches and local branches]" \
+    "($c $m $d : -v -vv --verbose)"{-v,-vv,--verbose}'[show SHA1 and commit subject line for each head]' \
+    "($c $m $d :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \
+    "($c $m $d :)--no-abbrev[don't abbreviate sha1s]" \
+    "($l $m $d)"{-l,--create-reflog}"[create the branch's reflog]" \
+    "($l $m $d -f --force)"{-f,--force}'[force the creation of a new branch]' \
+    "($l $m $d -t --track)"{-t,--track}'[setup configuration so that pull merges from the start point]' \
+    "($l $m $d)--no-track[override the branch.autosetupmerge configuration variable]" \
+    "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}'[set up configuration so that pull merges]:remote-branches:__git_remote_branch_names' \
+    "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \
+    "($l $m $d)*--contains=[only list branches that contain the specified commit]: :__git_committishs" \
+    "($l $m $d)*--no-contains=[only list branches that don't contain the specified commit]: :__git_committishs" \
+    "($l $m $d)--merged=[only list branches that are fully contained by HEAD]: :__git_committishs" \
+    "($l $m $d)--no-merged=[don't list branches that are fully contained by HEAD]: :__git_committishs" \
     "($c $l $m $d)--edit-description[edit branch description]" \
     $dependent_creation_args \
-    "($l $c $d $m $e)"{-m,--move}"[rename a branch and the corresponding reflog]" \
-    "($l $c $d $m $e)-M[rename a branch even if the new branch-name already exists]" \
+    "($l $c $d $m)"{-m,--move}"[rename a branch and the corresponding reflog]" \
+    "($l $c $d $m)-M[rename a branch even if the new branch-name already exists]" \
+    "($l $c $d $m)"{-c,--copy}"[copy a branch and the corresponding reflog]" \
+    "($l $c $d $m)-C[copy a branch even if the new branch-name already exists]" \
     $dependent_modification_args \
-    "($l $c $m $d $e)"{-d,--delete}"[delete a fully merged branch]" \
-    "($l $c $m $d $e)-D[delete a branch]" \
+    "($l $c $m $d)"{-d,--delete}"[delete a fully merged branch]" \
+    "($l $c $m $d)-D[delete a branch]" \
     {-q,--quiet}"[be more quiet]" \
     '*--sort=[specify field to sort on]: :__git_ref_sort_keys' \
     '--points-at=[only list tags of the given object]: :__git_commits' \
-    "($c $m $d $e -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
+    "($c $m $d -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
     $dependent_deletion_args
 }
 
@@ -929,6 +930,7 @@ _git-format-patch () {
     '--no-binary[do not output contents of changes in binary files, only note that they differ]' \
     '--root[treat the revision argument as a range]' \
     '--zero-commit[output all-zero hash in From header]' \
+    '--progress[show progress while generating patches]' \
     ': :->commit-or-commit-range' && ret=0
 
   case $state in
@@ -1126,6 +1128,22 @@ _git-init () {
     ':: :_directories'
 }
 
+(( $+functions[_git-interpret-trailers] )) ||
+_git-interpret-trailers() {
+  _arguments \
+    '--in-place[edit files in place]' \
+    '--trim-empty[trim empty trailers]' \
+    '--where[specify where to place the new trailer]' \
+    '--if-exists[specify action if trailer already exists]' \
+    '--if-missing[specify action if trailer is missing]' \
+    '--only-trailers[output only the trailers]' \
+    "--only-input[don't apply config rules]" \
+    '--unfold[join whitespace-continued values]' \
+    '--parse[set parsing options]' \
+    '--trailer[specify trailer(s) to add]' \
+    '*:file:_files'
+}
+
 (( $+functions[_git-log] )) ||
 _git-log () {
   local curcontext=$curcontext state line ret=1
@@ -1189,6 +1207,8 @@ _git-merge () {
     '--abort[restore the original branch and abort the merge operation]' \
     '--continue[continue the current in-progress merge]' \
     '--progress[force progress reporting]' \
+    '--signoff[add Signed-off-by:]' \
+    '--verify[verify commit-msg hook]' \
     '*: : __git_commits -O expl:git_commit_opts'
 }
 
@@ -1988,10 +2008,10 @@ _git-tag () {
       "*--no-contains=[only list tags that don't contain the specified commit]: :__git_commits" \
       '--merged=-[print only tags that are merged]:: :__git_commits' \
       '--no-merged=-[print only tags that are not merged]:: :__git_commits' \
-      '--sort=[specify how the tags should be sorted]:mode:((refname\:"lexicographic order"
-                                                             version\\\:refname\:"tag names are treated as version numbers"))' \
+      '--sort=[specify how the tags should be sorted]:field:__git_ref_sort_keys' \
       '--points-at=[only list tags of the given object]: :__git_commits' \
-      '--format=[specify format to use for the output]:format' \
+      '--format=[specify format to use for the output]:format:__git_format_ref' \
+      '--color=-[respect any colors specified in the format]::when:(always never auto)' \
       '(-i --ignore-case)'{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
       ':: :_guard "^-*" pattern' \
     - verification \
@@ -2186,6 +2206,7 @@ __git_config_option-or-value () {
     advice.implicitIdentity:'show advice when identity is guessed from system settings::->bool:true'
     advice.detachedHead:'show advice when entering detached-HEAD state::->bool:true'
     advice.amWorkDir:'show the location of the patch file when git-am fails to apply it::->bool:true'
+    advice.rmHints:'show directions in case of failure in the output of git-rm(1)::->bool:true'
     blame.blankboundary:'show blank SHA-1 for boundary commits::->bool:false'
     blame.showroot:'show root commits as normal commits::->bool:false'
     blame.date:'date format to use in output::__git_date_formats:iso'
@@ -3388,6 +3409,7 @@ _git-filter-branch () {
     '--original[namespace where original commits will be stored]:namespace:_directories' \
     '-d[temporary directory used for rewriting]: :_directories' \
     '(-f --force)'{-f,--force}'[force operation]' \
+    '--state-branch[load mapping from old to new objects from specified branch]:branch:__git_branch_names' \
     '*: :__git_commit_ranges'
 }
 
@@ -3504,16 +3526,6 @@ _git-reflog () {
   fi
 }
 
-(( $+functions[_git-relink] )) ||
-_git-relink () {
-  _arguments \
-    '--safe[stop if two objects with the same hash exist but have different sizes]' \
-    '(-)'{-h,--help}'[display usage information]' \
-    ': :_directories' \
-    ': :_directories' \
-    '*: :_directories'
-}
-
 (( $+functions[_git-remote] )) ||
 _git-remote () {
   local curcontext=$curcontext state line ret=1
@@ -3990,7 +4002,7 @@ _git-verify-tag () {
   _arguments -S -s \
     '(-v --verbose)'{-v,--verbose}'[print contents of the tag object before validating it]' \
     '--raw[print raw gpg status output]' \
-    '--format=[specify format to use for the output]:format' \
+    '--format=[specify format to use for the output]:format:__git_format_ref' \
     '*: :__git_tags'
 }
 
@@ -4915,7 +4927,8 @@ _git-for-each-ref () {
   _arguments -S -s \
     '--count=[maximum number of refs to iterate over]: :__git_guard_number "maximum number of refs"' \
     '*--sort=[key to sort refs by]: :__git_ref_sort_keys' \
-    '--format=-[output format of ref information]:format' \
+    '--format=-[output format of ref information]:format:__git_format_ref' \
+    '--color=-[respect any colors specified in the format]::when:(always never auto)' \
     '*--points-at=[print only refs which point at the given object]:object:__git_commits' \
     '*--merged=[print only refs that are merged]:object:__git_commits' \
     '*--no-merged=[print only refs that are not merged]:object:__git_commits' \
@@ -5640,7 +5653,6 @@ _git_commands () {
     pack-refs:'pack heads and tags for efficient repository access'
     prune:'prune all unreachable objects from the object database'
     reflog:'manage reflog information'
-    relink:'hardlink common objects in local repositories'
     remote:'manage set of tracked repositories'
     repack:'pack unpacked objects in a repository'
     replace:'create, list, delete refs to replace objects')
@@ -5654,6 +5666,7 @@ _git_commands () {
     get-tar-commit-id:'extract commit ID from an archive created using git archive'
     help:'display help information about git'
     instaweb:'instantly browse your working repository in gitweb'
+    interpret-trailers:'add or parse structured information in commit messages'
     merge-tree:'show three-way merge without touching index'
     rerere:'reuse recorded resolution of conflicted merges'
     rev-parse:'pick out and massage parameters for other git commands'
@@ -6026,17 +6039,80 @@ __git_reflog_entries () {
 __git_ref_sort_keys () {
   compset -P '-'
 
-  local -a sort_keys
+  __git_ref_fields "$@"
+}
 
-  # TODO: numparent is undocumented.
-  sort_keys=(
-    'refname:the name of the ref'
+(( $+functions[__git_ref_fields] )) ||
+__git_ref_fields () {
+  # pass -a to complete all fields, otherwise only fields relevant to sorting
+  local match mbegin mend
+  local -a cfields fields append opts all
+
+  zparseopts -D -E -a opts x: X: J: V: a=all
+
+  if compset -P 1 '(#b)(*):'; then
+    case $match[1] in
+      push|upstream)
+	append=(
+	  'trackshort[show terse version: > (ahead) < (behind) = (in sync)]'
+	  'track[print gone whenever unknown upstream ref is encountered]'
+	  'track,nobracket[tracking information without brackets]'
+        )
+      ;&
+      refname|upstream|symref)
+	append+=(
+	  {strip,lstrip}'[strip elements from the left]:elements to strip / -remain'
+	  'rstrip[strip elements from the right]:elements to strip / -remain'
+	  'short[strip to non-ambiguous short name]'
+	)
+      ;;
+      objectname)
+        append=(
+	  'short[strip to non-ambiguous short name]:length'
+	)
+      ;;
+      color)
+	_alternative \
+	  'colors::__git_colors' \
+	  'attributes::__git_color_attributes'
+	return
+      ;;
+      align)
+	append=(
+	  'width[specify width]:width'
+	  'position[specify alignment]:alignment:(left right middle)'
+	)
+      ;;
+      if) append=( {,not}'equals:string' ) ;;
+      contents) append=( subject body signature lines:lines ) ;;
+      tailers) append=( only unfold ) ;;
+      v|version)
+	append=(
+	  'refname[sort by versions]'
+	)
+      ;;
+    esac
+    (( $#append )) || return 1
+    _values 'interpolation modifier' $append
+    return
+  fi
+
+  cfields=(
+    'refname:name of the ref'
+    'objectname:object name (SHA-1)'
+    'upstream:name of a local ref which can be considered “upstream” from the displayed ref'
+    'push:name of a local ref which represents the @{push} location for the displayed ref'
+    'symref:the ref which the given symbolic ref refers to'
+    'contents:complete message'
+    'trailers:structured information in commit messages'
+  )
+  fields=(
     'objecttype:the type of the object'
     'objectsize:the size of the object'
-    'objectname:the object name (SHA-1)'
+    'HEAD:* if HEAD matches ref or space otherwise'
     'tree:the tree header-field'
     'parent:the parent header-field'
-    'numparent:undocumented'
+    'numparent:number of parent objects'
     'object:the object header-field'
     'type:the type header-field'
     'tag:the tag header-field'
@@ -6044,19 +6120,45 @@ __git_ref_sort_keys () {
     'authorname:the name component of the author header-field'
     'authoremail:the email component of the author header-field'
     'authordate:the date component of the author header-field'
+    'committer:the committer header-field'
     'committername:the name component of the committer header-field'
     'committeremail:the email component of the committer header-field'
     'committerdate:the date component of the committer header-field'
+    'tagger:the tagger header-field'
     'taggername:the name component of the tagger header-field'
     'taggeremail:the email component of the tagger header-field'
     'taggerdate:the date component of the tagger header-field'
-    'creatorname:the name component of the creator header-field'
+    'creator:the creator header-field'
     'creatordate:the date component of the creator header-field'
     'subject:the subject of the message'
     'body:the body of the message'
-    'body:the contents of the message (subject and body)')
+    'version\:refname:sort by versions'
+  )
+  if (( $#all )); then
+    cfields+=(
+      'color:change output color'
+      'align:set alignment'
+      'if:conditional'
+    )
+    fields+=(
+      'then:true branch'
+      'else:false branch'
+      'end:end if or align block'
+    )
+  fi
 
-  _describe -t sort-keys 'sort key' sort_keys $*
+  _describe -t fields 'field' cfields -S : -r ':\\) \t\n\-' -- fields "$@"
+}
+
+(( $+functions[__git_format_ref] )) ||
+__git_format_ref() {
+  local expl
+  compset -P '(%\\\([^)]#\\\)|[^%]|%%|%[[:xdigit:]][[:xdigit:]])#'
+  if compset -P '%\\\((\*|)'; then
+    __git_ref_fields -S '\)' -a
+  else
+    _wanted -x formats expl format compadd -S '' '%('
+  fi
 }
 
 (( $+functions[__git_signoff_file] )) ||
@@ -6984,7 +7086,14 @@ __git_setup_diff_stage_options () {
 __git_format_placeholders() {
   local sep
   local -a disp names placeholders expl
-  if compset -P 'format:'; then
+  _describe -t formats format '( oneline:"commit-ids and subject of messages"
+    short:"few headers and only subject of messages"
+    medium:"most parts of messages"
+    full:"all parts of commit messages"
+    fuller:"like full and includes dates"
+    email:"use email headers like From and Subject"
+    raw:"the raw commits" )' -- '( format:"specify own format" )' -S ':' && return
+  compset -P 'format:'
     compset -P '(%[^acgCG]|%?[^%]|[^%])#'
     if compset -P '%C'; then
       _wanted colors expl color compadd reset red green blue
@@ -7003,6 +7112,8 @@ __git_format_placeholders() {
 	gD:'reflog selector'
 	gd:'short reflog selector'
 	gn:'reflog identity'
+	ge:'reflog identity email'
+	gE:'reflog identity email (use .mailmap)'
 	gs:'reflog subject'
       )
       disp=( -l )
@@ -7026,8 +7137,8 @@ __git_format_placeholders() {
 	h:'abbreviated commit hash'
 	T:'tree hash'
 	t:'abbreviated tree hash'
-	P:'parent hash'
-	p:'abbreviated parent hash'
+	P:'parent hashes'
+	p:'abbreviated parent hashes'
 	a:'author details'
 	c:'committer details'
 	d:'ref name in brackets'
@@ -7058,15 +7169,6 @@ __git_format_placeholders() {
     fi
     _wanted placeholders expl placeholder \
         compadd -p % -S '' "$disp[@]" "$@" - "$names[@]"
-  else
-    _describe -t formats format '( oneline:"commit-ids and subject of messages"
-      short:"few headers and only subject of messages"
-      medium:"most parts of messages"
-      full:"all parts of commit messages"
-      fuller:"like full and includes dates"
-      email:"use email headers like From and Subject"
-      raw:"the raw commits" )' -- '( format:"specify own format" )' -S ':'
-  fi
 }
 
 (( $+functions[__git_setup_revision_options] )) ||


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: PATCH: update git completion
  2017-11-13 20:37 PATCH: update git completion Oliver Kiddle
@ 2017-11-14 12:29 ` Daniel Shahaf
  0 siblings, 0 replies; 2+ messages in thread
From: Daniel Shahaf @ 2017-11-14 12:29 UTC (permalink / raw)
  To: zsh-workers

Oliver Kiddle wrote on Mon, Nov 13, 2017 at 21:37:15 +0100:
> This brings git option completion up to 2.15.

Thanks.

> I also checked for other changes. git relink has gone at some point and
> git interpret-trailers was added. In the past, for custom formats, you
> needed git log --format=format:%... Now you can skip the format: part.
> 
> Completion for git tag/for-each-ref sort keys and formats is also
> improved.

Not specific for this patch, but in general, would you consider
splitting patches?  When the "add new options" and "improve existing
options" parts are mixed, they're harder to review.

Cheers,

Daniel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-11-14 12:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-13 20:37 PATCH: update git completion Oliver Kiddle
2017-11-14 12:29 ` Daniel Shahaf

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).