zsh-workers
 help / color / mirror / code / Atom feed
* git checkout @... completion
@ 2015-03-31 11:10 Robbie Gates
  2015-04-01  9:41 ` Daniel Shahaf
  0 siblings, 1 reply; 2+ messages in thread
From: Robbie Gates @ 2015-03-31 11:10 UTC (permalink / raw)
  To: zsh-workers


[-- Attachment #1.1: Type: text/plain, Size: 1454 bytes --]

Hi All,

  i've modified the git completions in _git to complete git checkout's
@{-n} syntax for recent branches. I'm pretty sure the way i've done it is
somewhat ugly, because my understanding of the completion system is
primitive. I've attached a patch (against a local copy) - please let me
know if it's better to submit changes as a PR and i'll do that.

  More importantly, any review comments before the patch is usable are most
welcome. In particular, it just offers the first for each unique amongst
the most recent 9 branches. This is done by parsing the output of git log
--walk-reflogs using the same logic as git uses to interpret the @...
syntax according to my reading of sha1_name.c
<https://github.com/git/git/blob/e80e85a52adfda053cafc3b23058a86aff35404f/sha1_name.c#L930>
in
the git source using a bit of awkery. Although simplistic, i think this is
useful in practice.

  In particular, it could be rewritten to loop over git check-ref-format
--branch "@{-$i}" for increasing i until a given (by completion style
maybe, or environment variable) number of unique previous branches was
found. This felt a bit more rounadabout (and effort) than the quick version
here, but if it's more likely to be acceptable that this patch please let
me know and i'll rework it. Any pointers to completions with a configurable
depth / length that i could use to glean the right way to do this kind of
thing welcome.

  Thanks for your time,

 - Robbie

[-- Attachment #1.2: Type: text/html, Size: 1661 bytes --]

[-- Attachment #2: _git.patch --]
[-- Type: application/octet-stream, Size: 2379 bytes --]

diff --git a/functions/_git b/functions/_git
index c4e386b..884756c 100644
--- a/functions/_git
+++ b/functions/_git
@@ -463,27 +463,37 @@ _git-checkout () {
         local branch_arg='branches::__git_revisions' \
               remote_branch_noprefix_arg='remote branches::__git_remote_branch_names_noprefix' \
               tree_ish_arg='tree-ishs::__git_tree_ishs' \
-              file_arg='modified-files::__git_modified_files'
+              file_arg='modified-files::__git_modified_files' \
+              previous_arg='previous-branches::__git_previous_branches'
 
         if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then
           remote_branch_noprefix_arg=
           tree_ish_arg=
           file_arg=
+          previous_arg=
         elif [[ -n $opt_args[(I)--track] ]]; then
           branch_arg='remote-branches::__git_remote_branch_names'
           remote_branch_noprefix_arg=
           tree_ish_arg=
           file_arg=
+          previous_arg=
         elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then
           branch_arg=
           remote_branch_noprefix_arg=
+          previous_arg=
+        elif [[ $line[CURRENT] = @* ]]; then
+          branch_arg=
+          remote_branch_noprefix_arg=
+          tree_ish_arg=
+          file_arg=
         fi
 
         _alternative \
           $branch_arg \
           $remote_branch_noprefix_arg \
           $tree_ish_arg \
-          $file_arg && ret=0
+          $file_arg \
+          $previous_arg && ret=0
       elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then
         _nothing
       elif [[ -n $line[1] ]] && __git_is_treeish $line[1]; then
@@ -5769,6 +5779,14 @@ __git_notes_refs () {
   _wanted notes-refs expl 'notes ref' compadd $* - $notes_refs
 }
 
+(( $+functions[__git_previous_branches] )) ||
+__git_previous_branches () {
+  declare -a previous_branches
+  # We don't need to escape : in branch names, because they can't be there (see git help check-ref-format)
+  previous_branches=(${(f)"$(_call_program previous-branches "git log --max-count=9 --walk-reflogs --grep-reflog '^checkout: moving from .* to' --format='%gs' 2>/dev/null" | awk '{if (!seen[$4]) { seen[$4]=1 ; print "@{-" NR "}:" $4 } }')"})
+  _describe "previous branch" previous_branches
+}
+
 # File Argument Types
 
 (( $+functions[__git_files_relative] )) ||

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

end of thread, other threads:[~2015-04-01  9:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-31 11:10 git checkout @... completion Robbie Gates
2015-04-01  9:41 ` 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).