From da48616f1df51ff43acc64cdf8966f7b72142a11 Mon Sep 17 00:00:00 2001 From: Peter van der Does Date: Thu, 2 Dec 2010 02:17:13 -0600 Subject: bash: get --pretty=m completion to work with bash v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bash's programmable completion provides the COMP_WORDS array variable, which holds the individual words in the current command line. In bash versions prior to v4 "words are split on shell metacharacters as the shell parser would separate them" (quote from bash v3.2.48's man page). This behavior has changed with bash v4, and the command line "is split into words as readline would split it, using COMP_WORDBREAKS as" "the set of characters that the readline library treats as word separators" (quote from bash v4's man page). Since COMP_WORDBREAKS contains the characters : and = by default, this behavior change in bash affects git's completion script. For example, before bash 4, running $ git log --pretty=m would give a list of pretty-printing formats starting with 'm' but now it completes on branch names. It would be possible to work around this by removing '=' and ':' from COMP_WORDBREAKS, but as noticed in v1.5.6.4~9^2 (bash completion: Resolve git show ref:path losing ref: portion, 2008-07-15), that would break *other* completion scripts. The bash-completion library includes a better workaround: the _get_comp_words_by_ref function re-assembles a copy of COMP_WORDS, excluding a collection of word separators of the caller's choice. Use it. As a bonus, this also improves behavior when tab is pressed with the cursor in the middle of a word. To avoid breaking setups with the bash-completion library not already loaded, if the _get_comp_words_by_ref function is not defined then a shim that just reads COMP_WORDS will be used instead (no change from the current behavior in that case). Signed-off-by: Peter van der Does Signed-off-by: Jonathan Nieder Explained-by: SZEDER Gábor --- contrib/completion/git-completion.bash | 236 ++++++++++++++++++++++----------- 1 file changed, 160 insertions(+), 76 deletions(-) (limited to 'contrib') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 82e6609689..68b68d0c78 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -321,11 +321,39 @@ __gitcomp_1 () done } +if ! type _get_comp_words_by_ref >/dev/null 2>&1; then +_get_comp_words_by_ref () +{ + while [ $# -gt 0 ]; do + case "$1" in + cur) + cur=${COMP_WORDS[COMP_CWORD]} + ;; + prev) + prev=${COMP_WORDS[COMP_CWORD-1]} + ;; + words) + words=("${COMP_WORDS[@]}") + ;; + cword) + cword=$COMP_CWORD + ;; + -n) + # assume COMP_WORDBREAKS is already set sanely + shift + ;; + esac + shift + done +} +fi + # __gitcomp accepts 1, 2, 3, or 4 arguments # generates completion reply with compgen __gitcomp () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur if [ $# -gt 2 ]; then cur="$3" fi @@ -384,7 +412,8 @@ __git_tags () __git_refs () { local i is_hash=y dir="$(__gitdir "${1-}")" - local cur="${COMP_WORDS[COMP_CWORD]}" format refs + local cur format refs + _get_comp_words_by_ref -n =: cur if [ -d "$dir" ]; then case "$cur" in refs|refs/*) @@ -482,7 +511,8 @@ __git_compute_merge_strategies () __git_complete_file () { - local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}" + local pfx ls ref cur + _get_comp_words_by_ref -n =: cur case "$cur" in ?*:*) ref="${cur%%:*}" @@ -530,7 +560,8 @@ __git_complete_file () __git_complete_revlist () { - local pfx cur="${COMP_WORDS[COMP_CWORD]}" + local pfx cur + _get_comp_words_by_ref -n =: cur case "$cur" in *...*) pfx="${cur%...*}..." @@ -550,11 +581,12 @@ __git_complete_revlist () __git_complete_remote_or_refspec () { - local cmd="${COMP_WORDS[1]}" - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur words cword + _get_comp_words_by_ref -n =: cur words cword + local cmd="${words[1]}" local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 - while [ $c -lt $COMP_CWORD ]; do - i="${COMP_WORDS[c]}" + while [ $c -lt $cword ]; do + i="${words[c]}" case "$i" in --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;; --all) @@ -622,13 +654,14 @@ __git_complete_remote_or_refspec () __git_complete_strategy () { + local cur prev + _get_comp_words_by_ref -n =: cur prev __git_compute_merge_strategies - case "${COMP_WORDS[COMP_CWORD-1]}" in + case "$prev" in -s|--strategy) __gitcomp "$__git_merge_strategies" return 0 esac - local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --strategy=*) __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" @@ -788,10 +821,10 @@ __git_aliased_command () # __git_find_on_cmdline requires 1 argument __git_find_on_cmdline () { - local word subcommand c=1 - - while [ $c -lt $COMP_CWORD ]; do - word="${COMP_WORDS[c]}" + local word subcommand c=1 words cword + _get_comp_words_by_ref -n =: words cword + while [ $c -lt $cword ]; do + word="${words[c]}" for subcommand in $1; do if [ "$subcommand" = "$word" ]; then echo "$subcommand" @@ -804,9 +837,10 @@ __git_find_on_cmdline () __git_has_doubledash () { - local c=1 - while [ $c -lt $COMP_CWORD ]; do - if [ "--" = "${COMP_WORDS[c]}" ]; then + local c=1 words cword + _get_comp_words_by_ref -n =: words cword + while [ $c -lt $cword ]; do + if [ "--" = "${words[c]}" ]; then return 0 fi c=$((++c)) @@ -818,7 +852,8 @@ __git_whitespacelist="nowarn warn error error-all fix" _git_am () { - local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" + local cur dir="$(__gitdir)" + _get_comp_words_by_ref -n =: cur if [ -d "$dir"/rebase-apply ]; then __gitcomp "--skip --continue --resolved --abort" return @@ -842,7 +877,8 @@ _git_am () _git_apply () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" @@ -865,7 +901,8 @@ _git_add () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -879,7 +916,8 @@ _git_add () _git_archive () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --format=*) __gitcomp "$(git archive --list)" "" "${cur##--format=}" @@ -923,10 +961,11 @@ _git_bisect () _git_branch () { - local i c=1 only_local_ref="n" has_r="n" + local i c=1 only_local_ref="n" has_r="n" cur words cword - while [ $c -lt $COMP_CWORD ]; do - i="${COMP_WORDS[c]}" + _get_comp_words_by_ref -n =: cur words cword + while [ $c -lt $cword ]; do + i="${words[c]}" case "$i" in -d|-m) only_local_ref="y" ;; -r) has_r="y" ;; @@ -934,7 +973,7 @@ _git_branch () c=$((++c)) done - case "${COMP_WORDS[COMP_CWORD]}" in + case "$cur" in --*) __gitcomp " --color --no-color --verbose --abbrev= --no-abbrev @@ -954,8 +993,10 @@ _git_branch () _git_bundle () { - local cmd="${COMP_WORDS[2]}" - case "$COMP_CWORD" in + local words cword + _get_comp_words_by_ref -n =: words cword + local cmd="${words[2]}" + case "$cword" in 2) __gitcomp "create list-heads verify unbundle" ;; @@ -976,7 +1017,8 @@ _git_checkout () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --conflict=*) __gitcomp "diff3 merge" "" "${cur##--conflict=}" @@ -1000,7 +1042,8 @@ _git_cherry () _git_cherry_pick () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--edit --no-commit" @@ -1015,7 +1058,8 @@ _git_clean () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--dry-run --quiet" @@ -1027,7 +1071,8 @@ _git_clean () _git_clone () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -1054,7 +1099,8 @@ _git_commit () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --cleanup=*) __gitcomp "default strip verbatim whitespace @@ -1089,7 +1135,8 @@ _git_commit () _git_describe () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -1121,7 +1168,8 @@ _git_diff () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex @@ -1142,7 +1190,8 @@ _git_difftool () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}" @@ -1167,7 +1216,8 @@ __git_fetch_options=" _git_fetch () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "$__git_fetch_options" @@ -1179,7 +1229,8 @@ _git_fetch () _git_format_patch () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --thread=*) __gitcomp " @@ -1211,7 +1262,8 @@ _git_format_patch () _git_fsck () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -1226,7 +1278,8 @@ _git_fsck () _git_gc () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--prune --aggressive" @@ -1245,7 +1298,8 @@ _git_grep () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -1268,7 +1322,8 @@ _git_grep () _git_help () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--all --info --man --web" @@ -1286,7 +1341,8 @@ _git_help () _git_init () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --shared=*) __gitcomp " @@ -1306,7 +1362,8 @@ _git_ls_files () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--cached --deleted --modified --others --ignored @@ -1360,12 +1417,13 @@ _git_log () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(git rev-parse --git-dir 2>/dev/null)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats @@ -1419,7 +1477,8 @@ _git_merge () { __git_complete_strategy && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "$__git_merge_options" @@ -1430,7 +1489,8 @@ _git_merge () _git_mergetool () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" @@ -1451,7 +1511,8 @@ _git_merge_base () _git_mv () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--dry-run" @@ -1469,12 +1530,14 @@ _git_name_rev () _git_notes () { local subcommands="edit show" + local words cword + _get_comp_words_by_ref -n =: words cword if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then __gitcomp "$subcommands" return fi - case "${COMP_WORDS[COMP_CWORD-1]}" in + case "${words[cword-1]}" in -m|-F) COMPREPLY=() ;; @@ -1488,7 +1551,8 @@ _git_pull () { __git_complete_strategy && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -1504,8 +1568,9 @@ _git_pull () _git_push () { - local cur="${COMP_WORDS[COMP_CWORD]}" - case "${COMP_WORDS[COMP_CWORD-1]}" in + local cur prev + _get_comp_words_by_ref -n =: cur prev + case "$prev" in --repo) __gitcomp "$(__git_remotes)" return @@ -1528,7 +1593,9 @@ _git_push () _git_rebase () { - local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" + local dir="$(__gitdir)" + local cur + _get_comp_words_by_ref -n =: cur if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then __gitcomp "--continue --skip --abort" return @@ -1558,7 +1625,8 @@ __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all" _git_send_email () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --confirm=*) __gitcomp " @@ -1600,9 +1668,11 @@ _git_stage () __git_config_get_set_variables () { - local prevword word config_file= c=$COMP_CWORD + local words cword + _get_comp_words_by_ref -n =: words cword + local prevword word config_file= c=$cword while [ $c -gt 1 ]; do - word="${COMP_WORDS[c]}" + word="${words[c]}" case "$word" in --global|--system|--file=*) config_file="$word" @@ -1630,9 +1700,9 @@ __git_config_get_set_variables () _git_config () { - local cur="${COMP_WORDS[COMP_CWORD]}" - local prv="${COMP_WORDS[COMP_CWORD-1]}" - case "$prv" in + local cur prev + _get_comp_words_by_ref -n =: cur prev + case "$prev" in branch.*.remote) __gitcomp "$(__git_remotes)" return @@ -1642,13 +1712,13 @@ _git_config () return ;; remote.*.fetch) - local remote="${prv#remote.}" + local remote="${prev#remote.}" remote="${remote%.fetch}" __gitcomp "$(__git_refs_remotes "$remote")" return ;; remote.*.push) - local remote="${prv#remote.}" + local remote="${prev#remote.}" remote="${remote%.push}" __gitcomp "$(git --git-dir="$(__gitdir)" \ for-each-ref --format='%(refname):%(refname)' \ @@ -2039,7 +2109,8 @@ _git_reset () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--merge --mixed --hard --soft --patch" @@ -2051,7 +2122,8 @@ _git_reset () _git_revert () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--edit --mainline --no-edit --no-commit --signoff" @@ -2065,7 +2137,8 @@ _git_rm () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--cached --dry-run --ignore-unmatch --quiet" @@ -2079,7 +2152,8 @@ _git_shortlog () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -2097,7 +2171,8 @@ _git_show () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats @@ -2121,7 +2196,8 @@ _git_show () _git_show_branch () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " @@ -2138,7 +2214,8 @@ _git_show_branch () _git_stash () { - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur local save_opts='--keep-index --no-keep-index --quiet --patch' local subcommands='save list show apply clear drop pop create branch' local subcommand="$(__git_find_on_cmdline "$subcommands")" @@ -2183,7 +2260,8 @@ _git_submodule () local subcommands="add status init update summary foreach sync" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp "--quiet --cached" @@ -2227,7 +2305,8 @@ _git_svn () --edit --rmdir --find-copies-harder --copy-similarity= " - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur + _get_comp_words_by_ref -n =: cur case "$subcommand,$cur" in fetch,--*) __gitcomp "--revision= --fetch-all $fc_opts" @@ -2299,8 +2378,10 @@ _git_svn () _git_tag () { local i c=1 f=0 - while [ $c -lt $COMP_CWORD ]; do - i="${COMP_WORDS[c]}" + local words cword prev + _get_comp_words_by_ref -n =: words cword prev + while [ $c -lt $cword ]; do + i="${words[c]}" case "$i" in -d|-v) __gitcomp "$(__git_tags)" @@ -2313,7 +2394,7 @@ _git_tag () c=$((++c)) done - case "${COMP_WORDS[COMP_CWORD-1]}" in + case "$prev" in -m|-F) COMPREPLY=() ;; @@ -2339,8 +2420,10 @@ _git () { local i c=1 command __git_dir - while [ $c -lt $COMP_CWORD ]; do - i="${COMP_WORDS[c]}" + local cur words cword + _get_comp_words_by_ref -n =: cur words cword + while [ $c -lt $cword ]; do + i="${words[c]}" case "$i" in --git-dir=*) __git_dir="${i#--git-dir=}" ;; --bare) __git_dir="." ;; @@ -2352,7 +2435,7 @@ _git () done if [ -z "$command" ]; then - case "${COMP_WORDS[COMP_CWORD]}" in + case "$cur" in --*) __gitcomp " --paginate --no-pager @@ -2385,12 +2468,13 @@ _gitk () { __git_has_doubledash && return - local cur="${COMP_WORDS[COMP_CWORD]}" + local cur local g="$(__gitdir)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi + _get_comp_words_by_ref -n =: cur case "$cur" in --*) __gitcomp " -- cgit v1.2.1 From dbda3b10902e13826862505900eb7a537505a492 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 14 Dec 2010 22:57:58 -0600 Subject: bash: simple reimplementation of _get_comp_words_by_ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a minimal implementation of _get_comp_words_by_ref so $ git show head:g on bash 4 can complete paths within the head commit without requiring the bash_completion functions to be loaded. This is a follow-up to the previous patch (bash: get --pretty=m completion to work with bash v4). Based on bash-completion 2.x (commit bf763033, 2010-10-26) but tweaked for simplicity and to allow zsh to parse the code. Signed-off-by: Jonathan Nieder Improved-by: SZEDER Gábor --- contrib/completion/git-completion.bash | 118 ++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 8 deletions(-) (limited to 'contrib') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 68b68d0c78..1747091287 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -321,26 +321,128 @@ __gitcomp_1 () done } +# The following function is based on code from: +# +# bash_completion - programmable completion functions for bash 3.2+ +# +# Copyright © 2006-2008, Ian Macdonald +# © 2009-2010, Bash Completion Maintainers +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The latest version of this software can be obtained here: +# +# http://bash-completion.alioth.debian.org/ +# +# RELEASE: 2.x + +# This function can be used to access a tokenized list of words +# on the command line: +# +# __git_reassemble_comp_words_by_ref '=:' +# if test "${words_[cword_-1]}" = -w +# then +# ... +# fi +# +# The argument should be a collection of characters from the list of +# word completion separators (COMP_WORDBREAKS) to treat as ordinary +# characters. +# +# This is roughly equivalent to going back in time and setting +# COMP_WORDBREAKS to exclude those characters. The intent is to +# make option types like --date= and : easy to +# recognize by treating each shell word as a single token. +# +# It is best not to set COMP_WORDBREAKS directly because the value is +# shared with other completion scripts. By the time the completion +# function gets called, COMP_WORDS has already been populated so local +# changes to COMP_WORDBREAKS have no effect. +# +# Output: words_, cword_, cur_. + +__git_reassemble_comp_words_by_ref() +{ + local exclude i j first + # Which word separators to exclude? + exclude="${1//[^$COMP_WORDBREAKS]}" + cword_=$COMP_CWORD + if [ -z "$exclude" ]; then + words_=("${COMP_WORDS[@]}") + return + fi + # List of word completion separators has shrunk; + # re-assemble words to complete. + for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do + # Append each nonempty word consisting of just + # word separator characters to the current word. + first=t + while + [ $i -gt 0 ] && + [ -n "${COMP_WORDS[$i]}" ] && + # word consists of excluded word separators + [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] + do + # Attach to the previous token, + # unless the previous token is the command name. + if [ $j -ge 2 ] && [ -n "$first" ]; then + ((j--)) + fi + first= + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + if (($i < ${#COMP_WORDS[@]} - 1)); then + ((i++)) + else + # Done. + return + fi + done + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + done +} + if ! type _get_comp_words_by_ref >/dev/null 2>&1; then _get_comp_words_by_ref () { + local exclude cur_ words_ cword_ + if [ "$1" = "-n" ]; then + exclude=$2 + shift 2 + fi + __git_reassemble_comp_words_by_ref "$exclude" + cur_=${words_[cword_]} while [ $# -gt 0 ]; do case "$1" in cur) - cur=${COMP_WORDS[COMP_CWORD]} + cur=$cur_ ;; prev) - prev=${COMP_WORDS[COMP_CWORD-1]} + prev=${words_[$cword_-1]} ;; words) - words=("${COMP_WORDS[@]}") + words=("${words_[@]}") ;; cword) - cword=$COMP_CWORD - ;; - -n) - # assume COMP_WORDBREAKS is already set sanely - shift + cword=$cword_ ;; esac shift -- cgit v1.2.1