completion: add new __git_complete helper
[gitweb.git] / contrib / completion / git-completion.bash
index 33f0e4dd696c73ffca2b9d2c3955661f1cdd00cd..d60bb8ac8f62d44cafea3282867be158c6b68cbb 100755 (executable)
@@ -94,9 +94,10 @@ __gitdir ()
 __git_ps1_show_upstream ()
 {
        local key value
-       local svn_remote=() svn_url_pattern count n
+       local svn_remote svn_url_pattern count n
        local upstream=git legacy="" verbose=""
 
+       svn_remote=()
        # get some config options from git-config
        local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
        while read -r key value; do
@@ -303,16 +304,16 @@ __git_ps1 ()
        fi
 }
 
-# __gitcomp_1 requires 2 arguments
 __gitcomp_1 ()
 {
-       local c IFS=' '$'\t'$'\n'
+       local c IFS=$' \t\n'
        for c in $1; do
-               case "$c$2" in
-               --*=*) printf %s$'\n' "$c$2" ;;
-               *.)    printf %s$'\n' "$c$2" ;;
-               *)     printf %s$'\n' "$c$2 " ;;
+               c="$c$2"
+               case $c in
+               --*=*|*.) ;;
+               *) c="$c " ;;
                esac
+               printf '%s\n' "$c"
        done
 }
 
@@ -1657,7 +1658,7 @@ _git_notes ()
                __gitcomp '--ref'
                ;;
        ,*)
-               case "${words[cword-1]}" in
+               case "$prev" in
                --ref)
                        __gitcomp_nl "$(__git_refs)"
                        ;;
@@ -1683,7 +1684,7 @@ _git_notes ()
        prune,*)
                ;;
        *)
-               case "${words[cword-1]}" in
+               case "$prev" in
                -m|-F)
                        ;;
                *)
@@ -2092,6 +2093,7 @@ _git_config ()
                core.whitespace
                core.worktree
                diff.autorefreshindex
+               diff.statGraphWidth
                diff.external
                diff.ignoreSubmodules
                diff.mnemonicprefix
@@ -2601,28 +2603,14 @@ _git ()
 {
        local i c=1 command __git_dir
 
-       if [[ -n ${ZSH_VERSION-} ]]; then
-               emulate -L bash
-               setopt KSH_TYPESET
-
-               # workaround zsh's bug that leaves 'words' as a special
-               # variable in versions < 4.3.12
-               typeset -h words
-
-               # workaround zsh's bug that quotes spaces in the COMPREPLY
-               # array if IFS doesn't contain spaces.
-               typeset -h IFS
-       fi
-
-       local cur words cword prev
-       _get_comp_words_by_ref -n =: cur words cword prev
        while [ $c -lt $cword ]; do
                i="${words[c]}"
                case "$i" in
                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
                --bare)      __git_dir="." ;;
-               --version|-p|--paginate) ;;
                --help) command="help"; break ;;
+               -c) c=$((++c)) ;;
+               -*) ;;
                *) command="$i"; break ;;
                esac
                ((c++))
@@ -2637,9 +2625,12 @@ _git ()
                        --bare
                        --version
                        --exec-path
+                       --exec-path=
                        --html-path
+                       --info-path
                        --work-tree=
                        --namespace=
+                       --no-replace-objects
                        --help
                        "
                        ;;
@@ -2661,22 +2652,6 @@ _git ()
 
 _gitk ()
 {
-       if [[ -n ${ZSH_VERSION-} ]]; then
-               emulate -L bash
-               setopt KSH_TYPESET
-
-               # workaround zsh's bug that leaves 'words' as a special
-               # variable in versions < 4.3.12
-               typeset -h words
-
-               # workaround zsh's bug that quotes spaces in the COMPREPLY
-               # array if IFS doesn't contain spaces.
-               typeset -h IFS
-       fi
-
-       local cur words cword prev
-       _get_comp_words_by_ref -n =: cur words cword prev
-
        __git_has_doubledash && return
 
        local g="$(__gitdir)"
@@ -2697,16 +2672,43 @@ _gitk ()
        __git_complete_revlist
 }
 
-complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
-       || complete -o default -o nospace -F _git git
-complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
-       || complete -o default -o nospace -F _gitk gitk
+__git_func_wrap ()
+{
+       if [[ -n ${ZSH_VERSION-} ]]; then
+               emulate -L bash
+               setopt KSH_TYPESET
+
+               # workaround zsh's bug that leaves 'words' as a special
+               # variable in versions < 4.3.12
+               typeset -h words
+
+               # workaround zsh's bug that quotes spaces in the COMPREPLY
+               # array if IFS doesn't contain spaces.
+               typeset -h IFS
+       fi
+       local cur words cword prev
+       _get_comp_words_by_ref -n =: cur words cword prev
+       $1
+}
+
+# Setup completion for certain functions defined above by setting common
+# variables and workarounds.
+# This is NOT a public function; use at your own risk.
+__git_complete ()
+{
+       local wrapper="__git_wrap${2}"
+       eval "$wrapper () { __git_func_wrap $2 ; }"
+       complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
+               || complete -o default -o nospace -F $wrapper $1
+}
+
+__git_complete git _git
+__git_complete gitk _gitk
 
 # The following are necessary only for Cygwin, and only are needed
 # when the user has tab-completed the executable name and consequently
 # included the '.exe' suffix.
 #
 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
-       || complete -o default -o nospace -F _git git.exe
+__git_complete git.exe _git
 fi