{"thread":{"id":"25918","subject":"[PATCH v5 0/2] Make git-completion Bash 4 compatible.","startedAt":"2010-12-02T00:40:42Z","lastAt":"2010-12-02T00:40:44Z","messageCount":3,"participants":["Peter van der Does"],"isPatch":true,"patchVersion":5,"patchTotal":2},"messages":[{"id":"157063","messageId":"1291250444-1832-1-git-send-email-peter@avirtualhome.com","threadId":"25918","inReplyTo":null,"subject":"[PATCH v5 0/2] Make git-completion Bash 4 compatible.","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-02T00:40:42Z","receivedAt":"2010-12-02T00:40:42Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"Updates since v4\n- Patch is based on master again. My mistake.\n\nPeter van der Does (2):\n  Introduce functions from bash-completion project.\n  Use the new functions to get the current cword.\n\n contrib/completion/git-completion.bash |  446 ++++++++++++++++++++++++++------\n 1 files changed, 363 insertions(+), 83 deletions(-)\n\n-- \n1.7.3.2\n"},{"id":"157065","messageId":"1291250444-1832-2-git-send-email-peter@avirtualhome.com","threadId":"25918","inReplyTo":"1291250444-1832-1-git-send-email-peter@avirtualhome.com","subject":"[PATCH v5 1/2] Introduce functions from bash-completion project.","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-02T00:40:43Z","receivedAt":"2010-12-02T00:40:43Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"The completion script does not work as expected under Bash 4.\nBash: 3\noutput:\n$ git log --pretty=<tab><tab>\nemail     full      medium    raw\nformat:   fuller    oneline   short\n\nBash: 4\noutput:\n$ git log --pretty=<tab><tab>\n.bash_logout         .local/\n.bash_profile        Music/\n--More--\n\nWith Bash 4 the way word breaking is done in the programmable completion\ncode has changed. The documentation at the bash project is not very\nclear what was changed, the only reference found is in the NEWS section:\n\ni.  The programmable completion code now uses the same set of characters\nas readline when breaking the command line into a list of words.\n\nThe word breaking problem occurs with certain characters, like colon and\nequal sign.\n\nThe bash-completion project (http://bash-completion.alioth.debian.org/)\nhas written several functions to overcome this problem. By using these\nfunctions within the git-completion.bash script the word breaking\nproblem is solved.\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\n---\n contrib/completion/git-completion.bash |  223 ++++++++++++++++++++++++++++++++\n 1 files changed, 223 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f710469..0036e8b 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -82,6 +82,229 @@ case \"$COMP_WORDBREAKS\" in\n *)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n esac\n \n+# If the function _get_comp_words_by_ref does not exists, we can assume the\n+# bash_completion 1.2 script isn't loaded and therefor we're defining the\n+# necessary functions ourselves.\n+# The functions come from the bash_completion 1.2 script.\n+# See: http://bash-completion.alioth.debian.org/\n+if ! type _get_comp_words_by_ref &> /dev/null ; then\n+\t# The bash_completion 1.2 library wasn't loaded,\n+\t# we have to define some functions from it ourselves.\n+\n+\t# Assign variables one scope above the caller\n+\t# Usage: local varname [varname ...] &&\n+\t#        _upvars [-v varname value] | [-aN varname [value ...]] ...\n+\t# Available OPTIONS:\n+\t#     -aN  Assign next N values to varname as array\n+\t#     -v   Assign single value to varname\n+\t# Return: 1 if error occurs\n+\t# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference\n+\t_upvars() {\n+\t    if ! (( $# )); then\n+\t        echo \"${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname\"\\\n+\t            \"value] | [-aN varname [value ...]] ...\" 1>&2\n+\t        return 2\n+\t    fi\n+\t    while (( $# )); do\n+\t        case $1 in\n+\t            -a*)\n+\t                # Error checking\n+\t                [[ ${1#-a} ]] || { echo \"bash: ${FUNCNAME[0]}: \\`$1': missing\"\\\n+\t                    \"number specifier\" 1>&2; return 1; }\n+\t                printf %d \"${1#-a}\" &> /dev/null || { echo \"bash:\"\\\n+\t                    \"${FUNCNAME[0]}: \\`$1': invalid number specifier\" 1>&2\n+\t                    return 1; }\n+\t                # Assign array of -aN elements\n+\t                [[ \"$2\" ]] && unset -v \"$2\" && eval $2=\\(\\\"\\${@:3:${1#-a}}\\\"\\) &&\n+\t                shift $((${1#-a} + 2)) || { echo \"bash: ${FUNCNAME[0]}:\"\\\n+\t                    \"\\`$1${2+ }$2': missing argument(s)\" 1>&2; return 1; }\n+\t                ;;\n+\t            -v)\n+\t                # Assign single value\n+\t                [[ \"$2\" ]] && unset -v \"$2\" && eval $2=\\\"\\$3\\\" &&\n+\t                shift 3 || { echo \"bash: ${FUNCNAME[0]}: $1: missing\"\\\n+\t                \"argument(s)\" 1>&2; return 1; }\n+\t                ;;\n+\t            *)\n+\t                echo \"bash: ${FUNCNAME[0]}: $1: invalid option\" 1>&2\n+\t                return 1 ;;\n+\t        esac\n+\t    done\n+\t}\n+\n+\n+\t# Reassemble command line words, excluding specified characters from the\n+\t# list of word completion separators (COMP_WORDBREAKS).\n+\t# @param $1 chars  Characters out of $COMP_WORDBREAKS which should\n+\t#     NOT be considered word breaks. This is useful for things like scp where\n+\t#     we want to return host:path and not only path, so we would pass the\n+\t#     colon (:) as $1 here.\n+\t# @param $2 words  Name of variable to return words to\n+\t# @param $3 cword  Name of variable to return cword to\n+\t#\n+\t__reassemble_comp_words_by_ref() {\n+\t    local exclude i j ref\n+\t    # Exclude word separator characters?\n+\t    if [[ $1 ]]; then\n+\t        # Yes, exclude word separator characters;\n+\t        # Exclude only those characters, which were really included\n+\t        exclude=\"${1//[^$COMP_WORDBREAKS]}\"\n+\t    fi\n+\n+\t    # Default to cword unchanged\n+\t    eval $3=$COMP_CWORD\n+\t    # Are characters excluded which were former included?\n+\t    if [[ $exclude ]]; then\n+\t        # Yes, list of word completion separators has shrunk;\n+\t        # Re-assemble words to complete\n+\t        for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t            # Is current word not word 0 (the command itself) and is word not\n+\t            # empty and is word made up of just word separator characters to be\n+\t            # excluded?\n+\t            while [[ $i -gt 0 && ${COMP_WORDS[$i]} &&\n+\t                ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]}\n+\t            ]]; do\n+\t                [ $j -ge 2 ] && ((j--))\n+\t                # Append word separator to current word\n+\t                ref=\"$2[$j]\"\n+\t                eval $2[$j]=\\${!ref}\\${COMP_WORDS[i]}\n+\t                # Indicate new cword\n+\t                [ $i = $COMP_CWORD ] && eval $3=$j\n+\t                # Indicate next word if available, else end *both* while and for loop\n+\t                (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2\n+\t            done\n+\t            # Append word to current word\n+\t            ref=\"$2[$j]\"\n+\t            eval $2[$j]=\\${!ref}\\${COMP_WORDS[i]}\n+\t            # Indicate new cword\n+\t            [ $i = $COMP_CWORD ] && [[ ${COMP_WORDS[i]} ]] && eval $3=$j\n+\t        done\n+\t    else\n+\t        # No, list of word completions separators hasn't changed;\n+\t        eval $2=\\( \\\"\\${COMP_WORDS[@]}\\\" \\)\n+\t    fi\n+\t} # __reassemble_comp_words_by_ref()\n+\n+\t# @param $1 exclude  Characters out of $COMP_WORDBREAKS which should NOT be\n+\t#     considered word breaks. This is useful for things like scp where\n+\t#     we want to return host:path and not only path, so we would pass the\n+\t#     colon (:) as $1 in this case.  Bash-3 doesn't do word splitting, so this\n+\t#     ensures we get the same word on both bash-3 and bash-4.\n+\t# @param $2 words  Name of variable to return words to\n+\t# @param $3 cword  Name of variable to return cword to\n+\t# @param $4 cur  Name of variable to return current word to complete to\n+\t# @see ___get_cword_at_cursor_by_ref()\n+\t__get_cword_at_cursor_by_ref() {\n+\t    local cword words=()\n+\t    __reassemble_comp_words_by_ref \"$1\" words cword\n+\n+\t    local i cur2\n+\t    local cur=\"$COMP_LINE\"\n+\t    local index=\"$COMP_POINT\"\n+\t    for (( i = 0; i <= cword; ++i )); do\n+\t        while [[\n+\t            # Current word fits in $cur?\n+\t            \"${#cur}\" -ge ${#words[i]} &&\n+\t            # $cur doesn't match cword?\n+\t            \"${cur:0:${#words[i]}}\" != \"${words[i]}\"\n+\t        ]]; do\n+\t            # Strip first character\n+\t            cur=\"${cur:1}\"\n+\t            # Decrease cursor position\n+\t            ((index--))\n+\t        done\n+\n+\t        # Does found word matches cword?\n+\t        if [[ \"$i\" -lt \"$cword\" ]]; then\n+\t            # No, cword lies further;\n+\t            local old_size=\"${#cur}\"\n+\t            cur=\"${cur#${words[i]}}\"\n+\t            local new_size=\"${#cur}\"\n+\t            index=$(( index - old_size + new_size ))\n+\t        fi\n+\t    done\n+\n+\t    if [[ \"${words[cword]:0:${#cur}}\" != \"$cur\" ]]; then\n+\t        # We messed up. At least return the whole word so things keep working\n+\t        cur2=${words[cword]}\n+\t    else\n+\t        cur2=${cur:0:$index}\n+\t    fi\n+\n+\t    local \"$2\" \"$3\" \"$4\" &&\n+\t        _upvars -a${#words[@]} $2 \"${words[@]}\" -v $3 \"$cword\" -v $4 \"$cur2\"\n+\t}\n+\n+\n+\t# Get the word to complete and optional previous words.\n+\t# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases\n+\t# where the user is completing in the middle of a word.\n+\t# (For example, if the line is \"ls foobar\",\n+\t# and the cursor is here -------->   ^\n+\t# Also one is able to cross over possible wordbreak characters.\n+\t# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]\n+\t# Available VARNAMES:\n+\t#     cur         Return cur via $cur\n+\t#     prev        Return prev via $prev\n+\t#     words       Return words via $words\n+\t#     cword       Return cword via $cword\n+\t#\n+\t# Available OPTIONS:\n+\t#     -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be\n+\t#                 considered word breaks. This is useful for things like scp\n+\t#                 where we want to return host:path and not only path, so we\n+\t#                 would pass the colon (:) as -n option in this case.  Bash-3\n+\t#                 doesn't do word splitting, so this ensures we get the same\n+\t#                 word on both bash-3 and bash-4.\n+\t#     -c VARNAME  Return cur via $VARNAME\n+\t#     -p VARNAME  Return prev via $VARNAME\n+\t#     -w VARNAME  Return words via $VARNAME\n+\t#     -i VARNAME  Return cword via $VARNAME\n+\t#\n+\t# Example usage:\n+\t#\n+\t#    $ _get_comp_words_by_ref -n : cur prev\n+\t#\n+\t_get_comp_words_by_ref()\n+\t{\n+\t    local exclude flag i OPTIND=1\n+\t    local cur cword words=()\n+\t    local upargs=() upvars=() vcur vcword vprev vwords\n+\n+\t    while getopts \"c:i:n:p:w:\" flag \"$@\"; do\n+\t        case $flag in\n+\t            c) vcur=$OPTARG ;;\n+\t            i) vcword=$OPTARG ;;\n+\t            n) exclude=$OPTARG ;;\n+\t            p) vprev=$OPTARG ;;\n+\t            w) vwords=$OPTARG ;;\n+\t        esac\n+\t    done\n+\t    while [[ $# -ge $OPTIND ]]; do\n+\t        case ${!OPTIND} in\n+\t            cur)   vcur=cur ;;\n+\t            prev)  vprev=prev ;;\n+\t            cword) vcword=cword ;;\n+\t            words) vwords=words ;;\n+\t            *) echo \"bash: $FUNCNAME(): \\`${!OPTIND}': unknown argument\" \\\n+\t                1>&2; return 1\n+\t        esac\n+\t        let \"OPTIND += 1\"\n+\t    done\n+\n+\t    __get_cword_at_cursor_by_ref \"$exclude\" words cword cur\n+\n+\t    [[ $vcur   ]] && { upvars+=(\"$vcur\"  ); upargs+=(-v $vcur   \"$cur\"  ); }\n+\t    [[ $vcword ]] && { upvars+=(\"$vcword\"); upargs+=(-v $vcword \"$cword\"); }\n+\t    [[ $vprev  ]] && { upvars+=(\"$vprev\" ); upargs+=(-v $vprev\n+\t        \"${words[cword - 1]}\"); }\n+\t    [[ $vwords ]] && { upvars+=(\"$vwords\"); upargs+=(-a${#words[@]} $vwords\n+\t        \"${words[@]}\"); }\n+\n+\t    (( ${#upvars[@]} )) && local \"${upvars[@]}\" && _upvars \"${upargs[@]}\"\n+\t}\n+fi\n+\n # __gitdir accepts 0 or 1 arguments (i.e., location)\n # returns location of .git repo\n __gitdir ()\n-- \n1.7.3.2\n"},{"id":"157064","messageId":"1291250444-1832-3-git-send-email-peter@avirtualhome.com","threadId":"25918","inReplyTo":"1291250444-1832-1-git-send-email-peter@avirtualhome.com","subject":"[PATCH v5 2/2] Use the new functions to get the current cword.","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-02T00:40:44Z","receivedAt":"2010-12-02T00:40:44Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"Change the completion functions to use the newly introduced functions to\nget the current and/or previous cword and to reassemble the COMP_CWORDS,\nmaking sure the options are correctly split.\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\n---\n contrib/completion/git-completion.bash |  223 ++++++++++++++++++++------------\n 1 files changed, 140 insertions(+), 83 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 0036e8b..f915e1f 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -554,7 +554,8 @@ __gitcomp_1 ()\n # generates completion reply with compgen\n __gitcomp ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ $# -gt 2 ]; then\n \t\tcur=\"$3\"\n \tfi\n@@ -615,7 +616,8 @@ __git_tags ()\n __git_refs ()\n {\n \tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\" track=\"${2-}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n+\tlocal cur format refs\n+\t_get_comp_words_by_ref cur\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n@@ -729,7 +731,8 @@ __git_compute_merge_strategies ()\n \n __git_complete_file ()\n {\n-\tlocal pfx ls ref cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx ls ref cur\n+\t_get_comp_words_by_ref -n \":\" cur\n \tcase \"$cur\" in\n \t?*:*)\n \t\tref=\"${cur%%:*}\"\n@@ -777,7 +780,8 @@ __git_complete_file ()\n \n __git_complete_revlist ()\n {\n-\tlocal pfx cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t*...*)\n \t\tpfx=\"${cur%...*}...\"\n@@ -797,11 +801,13 @@ __git_complete_revlist ()\n \n __git_complete_remote_or_refspec ()\n {\n-\tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n \":\" cur words cword\n+\tlocal cmd=\"${words[1]}\"\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--mirror) [ \"$cmd\" = \"push\" ] && no_complete_refspec=1 ;;\n \t\t--all)\n@@ -869,13 +875,15 @@ __git_complete_remote_or_refspec ()\n \n __git_complete_strategy ()\n {\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n \t__git_compute_merge_strategies\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${prev}\" in\n \t-s|--strategy)\n \t\t__gitcomp \"$__git_merge_strategies\"\n \t\treturn 0\n \tesac\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\n \tcase \"$cur\" in\n \t--strategy=*)\n \t\t__gitcomp \"$__git_merge_strategies\" \"\" \"${cur##--strategy=}\"\n@@ -1048,10 +1056,11 @@ __git_aliased_command ()\n # __git_find_on_cmdline requires 1 argument\n __git_find_on_cmdline ()\n {\n-\tlocal word subcommand c=1\n+\tlocal word subcommand c=1 words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tword=\"${words[c]}\"\n \t\tfor subcommand in $1; do\n \t\t\tif [ \"$subcommand\" = \"$word\" ]; then\n \t\t\t\techo \"$subcommand\"\n@@ -1064,9 +1073,10 @@ __git_find_on_cmdline ()\n \n __git_has_doubledash ()\n {\n-\tlocal c=1\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n+\tlocal c=1, words cword\n+\t_get_comp_words_by_ref words cword\n+\twhile [ $c -lt $cwords ]; do\n+\t\tif [ \"--\" = \"${words[c]}\" ]; then\n \t\t\treturn 0\n \t\tfi\n \t\tc=$((++c))\n@@ -1078,7 +1088,9 @@ __git_whitespacelist=\"nowarn warn error error-all fix\"\n \n _git_am ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur dir=\"$(__gitdir)\"\n+\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ -d \"$dir\"/rebase-apply ]; then\n \t\t__gitcomp \"--skip --continue --resolved --abort\"\n \t\treturn\n@@ -1102,7 +1114,8 @@ _git_am ()\n \n _git_apply ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--whitespace=*)\n \t\t__gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n@@ -1125,7 +1138,8 @@ _git_add ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1139,7 +1153,8 @@ _git_add ()\n \n _git_archive ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--format=*)\n \t\t__gitcomp \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n@@ -1187,10 +1202,11 @@ _git_bisect ()\n \n _git_branch ()\n {\n-\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\"\n+\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\" cur words cword\n+\t_get_comp_words_by_ref cur words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-m)\tonly_local_ref=\"y\" ;;\n \t\t-r)\thas_r=\"y\" ;;\n@@ -1198,7 +1214,7 @@ _git_branch ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n \t\t\t--color --no-color --verbose --abbrev= --no-abbrev\n@@ -1218,8 +1234,10 @@ _git_branch ()\n \n _git_bundle ()\n {\n-\tlocal cmd=\"${COMP_WORDS[2]}\"\n-\tcase \"$COMP_CWORD\" in\n+\tlocal words cword\n+\t_get_comp_words_by_ref words cword\n+\tlocal cmd=\"${words[2]}\"\n+\tcase \"$cword\" in\n \t2)\n \t\t__gitcomp \"create list-heads verify unbundle\"\n \t\t;;\n@@ -1240,7 +1258,8 @@ _git_checkout ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--conflict=*)\n \t\t__gitcomp \"diff3 merge\" \"\" \"${cur##--conflict=}\"\n@@ -1270,7 +1289,8 @@ _git_cherry ()\n \n _git_cherry_pick ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --no-commit\"\n@@ -1285,7 +1305,8 @@ _git_clean ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n@@ -1297,7 +1318,8 @@ _git_clean ()\n \n _git_clone ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1324,7 +1346,8 @@ _git_commit ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--cleanup=*)\n \t\t__gitcomp \"default strip verbatim whitespace\n@@ -1359,7 +1382,8 @@ _git_commit ()\n \n _git_describe ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1391,7 +1415,8 @@ _git_diff ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --staged --pickaxe-all --pickaxe-regex\n@@ -1412,7 +1437,8 @@ _git_difftool ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common kompare\" \"\" \"${cur##--tool=}\"\n@@ -1437,7 +1463,8 @@ __git_fetch_options=\"\n \n _git_fetch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_fetch_options\"\n@@ -1449,7 +1476,8 @@ _git_fetch ()\n \n _git_format_patch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--thread=*)\n \t\t__gitcomp \"\n@@ -1481,7 +1509,8 @@ _git_format_patch ()\n \n _git_fsck ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1496,7 +1525,8 @@ _git_fsck ()\n \n _git_gc ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--prune --aggressive\"\n@@ -1515,7 +1545,8 @@ _git_grep ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1538,7 +1569,8 @@ _git_grep ()\n \n _git_help ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--all --info --man --web\"\n@@ -1556,7 +1588,8 @@ _git_help ()\n \n _git_init ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--shared=*)\n \t\t__gitcomp \"\n@@ -1576,7 +1609,8 @@ _git_ls_files ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --deleted --modified --others --ignored\n@@ -1630,7 +1664,8 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n@@ -1689,7 +1724,8 @@ _git_merge ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_merge_options\"\n@@ -1700,7 +1736,8 @@ _git_merge ()\n \n _git_mergetool ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common tortoisemerge\" \"\" \"${cur##--tool=}\"\n@@ -1721,7 +1758,8 @@ _git_merge_base ()\n \n _git_mv ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run\"\n@@ -1740,7 +1778,8 @@ _git_notes ()\n {\n \tlocal subcommands='add append copy edit list prune remove show'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n \n \tcase \"$subcommand,$cur\" in\n \t,--*)\n@@ -1775,7 +1814,7 @@ _git_notes ()\n \tprune,*)\n \t\t;;\n \t*)\n-\t\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\t\tcase \"${prev}\" in\n \t\t-m|-F)\n \t\t\t;;\n \t\t*)\n@@ -1790,7 +1829,8 @@ _git_pull ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1806,8 +1846,9 @@ _git_pull ()\n \n _git_push ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n+\tcase \"$prev\" in\n \t--repo)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1830,7 +1871,9 @@ _git_push ()\n \n _git_rebase ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur\n+\tlocal dir=\"$(__gitdir)\"\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ -d \"$dir\"/rebase-apply ] || [ -d \"$dir\"/rebase-merge ]; then\n \t\t__gitcomp \"--continue --skip --abort\"\n \t\treturn\n@@ -1860,7 +1903,8 @@ __git_send_email_suppresscc_options=\"author self cc bodycc sob cccmd body all\"\n \n _git_send_email ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--confirm=*)\n \t\t__gitcomp \"\n@@ -1902,9 +1946,10 @@ _git_stage ()\n \n __git_config_get_set_variables ()\n {\n-\tlocal prevword word config_file= c=$COMP_CWORD\n-\twhile [ $c -gt 1 ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\tlocal prevword word config_file= words cword\n+\t_get_comp_words_by_ref -n \"=\" words cword\n+\twhile [ $cword -gt 1 ]; do\n+\t\tword=\"${words[cword]}\"\n \t\tcase \"$word\" in\n \t\t--global|--system|--file=*)\n \t\t\tconfig_file=\"$word\"\n@@ -1916,7 +1961,7 @@ __git_config_get_set_variables ()\n \t\t\t;;\n \t\tesac\n \t\tprevword=$word\n-\t\tc=$((--c))\n+\t\tcword=$((--cword))\n \tdone\n \n \tgit --git-dir=\"$(__gitdir)\" config $config_file --list 2>/dev/null |\n@@ -1932,9 +1977,9 @@ __git_config_get_set_variables ()\n \n _git_config ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tlocal prv=\"${COMP_WORDS[COMP_CWORD-1]}\"\n-\tcase \"$prv\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref cur prev\n+\tcase \"$prev\" in\n \tbranch.*.remote)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1944,13 +1989,13 @@ _git_config ()\n \t\treturn\n \t\t;;\n \tremote.*.fetch)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.fetch}\"\n \t\t__gitcomp \"$(__git_refs_remotes \"$remote\")\"\n \t\treturn\n \t\t;;\n \tremote.*.push)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.push}\"\n \t\t__gitcomp \"$(git --git-dir=\"$(__gitdir)\" \\\n \t\t\tfor-each-ref --format='%(refname):%(refname)' \\\n@@ -2341,7 +2386,8 @@ _git_reset ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--merge --mixed --hard --soft --patch\"\n@@ -2353,7 +2399,8 @@ _git_reset ()\n \n _git_revert ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --mainline --no-edit --no-commit --signoff\"\n@@ -2367,7 +2414,8 @@ _git_rm ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur=\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n@@ -2381,7 +2429,8 @@ _git_shortlog ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2399,7 +2448,8 @@ _git_show ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats $(__git_pretty_aliases)\n@@ -2423,7 +2473,8 @@ _git_show ()\n \n _git_show_branch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2440,10 +2491,11 @@ _git_show_branch ()\n \n _git_stash ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal save_opts='--keep-index --no-keep-index --quiet --patch'\n \tlocal subcommands='save list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\t_get_comp_words_by_ref cur\n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$cur\" in\n \t\t--*)\n@@ -2485,7 +2537,8 @@ _git_submodule ()\n \n \tlocal subcommands=\"add status init update summary foreach sync\"\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref cur\n \t\tcase \"$cur\" in\n \t\t--*)\n \t\t\t__gitcomp \"--quiet --cached\"\n@@ -2529,7 +2582,8 @@ _git_svn ()\n \t\t\t--edit --rmdir --find-copies-harder --copy-similarity=\n \t\t\t\"\n \n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref cur\n \t\tcase \"$subcommand,$cur\" in\n \t\tfetch,--*)\n \t\t\t__gitcomp \"--revision= --fetch-all $fc_opts\"\n@@ -2600,9 +2654,10 @@ _git_svn ()\n \n _git_tag ()\n {\n-\tlocal i c=1 f=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal i c=1 f=0 words cword prev\n+\t_get_comp_words_by_ref prev words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-v)\n \t\t\t__gitcomp \"$(__git_tags)\"\n@@ -2615,7 +2670,7 @@ _git_tag ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${prev}\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -2639,15 +2694,16 @@ _git_whatchanged ()\n \n _git ()\n {\n-\tlocal i c=1 command __git_dir\n+\tlocal i c=1 command __git_dir words cword\n \n-\tif [[ -n ${ZSH_VERSION-} ]]; then\n+\tif [[ -n $ZSH_VERSION ]]; then\n \t\temulate -L bash\n \t\tsetopt KSH_TYPESET\n \tfi\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref -n \"=\" words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--git-dir=*) __git_dir=\"${i#--git-dir=}\" ;;\n \t\t--bare)      __git_dir=\".\" ;;\n@@ -2659,7 +2715,7 @@ _git ()\n \tdone\n \n \tif [ -z \"$command\" ]; then\n-\t\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\t\tcase \"${words[cword]}\" in\n \t\t--*)   __gitcomp \"\n \t\t\t--paginate\n \t\t\t--no-pager\n@@ -2690,19 +2746,20 @@ _git ()\n \n _gitk ()\n {\n-\tif [[ -n ${ZSH_VERSION-} ]]; then\n+\tif [[ -n $ZSH_VERSION ]]; then\n \t\temulate -L bash\n \t\tsetopt KSH_TYPESET\n \tfi\n \n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal g=\"$(__gitdir)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2730,7 +2787,7 @@ complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \\\n \t|| complete -o default -o nospace -F _git git.exe\n fi\n \n-if [[ -n ${ZSH_VERSION-} ]]; then\n+if [[ -n $ZSH_VERSION ]]; then\n \tshopt () {\n \t\tlocal option\n \t\tif [ $# -ne 2 ]; then\n-- \n1.7.3.2\n"}]}