Skip to content

Commit 5734fa4

Browse files
committed
Merge branch 'fc/completion'
In addition to a user visible change to offer more options to cherry-pick, generally cleans up and simplifies the code. * fc/completion: completion: small optimization completion: inline __gitcomp_1 to its sole callsite completion: get rid of compgen completion: add __gitcomp_nl tests completion: add new __gitcompadd helper completion: get rid of empty COMPREPLY assignments completion: trivial test improvement completion: add more cherry-pick options
2 parents bd1184c + ddc996d commit 5734fa4

File tree

2 files changed

+96
-47
lines changed

2 files changed

+96
-47
lines changed

contrib/completion/git-completion.bash

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,6 @@ __gitdir ()
5353
fi
5454
}
5555

56-
__gitcomp_1 ()
57-
{
58-
local c IFS=$' \t\n'
59-
for c in $1; do
60-
c="$c$2"
61-
case $c in
62-
--*=*|*.) ;;
63-
*) c="$c " ;;
64-
esac
65-
printf '%s\n' "$c"
66-
done
67-
}
68-
6956
# The following function is based on code from:
7057
#
7158
# bash_completion - programmable completion functions for bash 3.2+
@@ -195,8 +182,18 @@ _get_comp_words_by_ref ()
195182
}
196183
fi
197184

198-
# Generates completion reply with compgen, appending a space to possible
199-
# completion words, if necessary.
185+
__gitcompadd ()
186+
{
187+
local i=0
188+
for x in $1; do
189+
if [[ "$x" == "$3"* ]]; then
190+
COMPREPLY[i++]="$2$x$4"
191+
fi
192+
done
193+
}
194+
195+
# Generates completion reply, appending a space to possible completion words,
196+
# if necessary.
200197
# It accepts 1 to 4 arguments:
201198
# 1: List of possible completion words.
202199
# 2: A prefix to be added to each possible completion word (optional).
@@ -208,19 +205,25 @@ __gitcomp ()
208205

209206
case "$cur_" in
210207
--*=)
211-
COMPREPLY=()
212208
;;
213209
*)
214-
local IFS=$'\n'
215-
COMPREPLY=($(compgen -P "${2-}" \
216-
-W "$(__gitcomp_1 "${1-}" "${4-}")" \
217-
-- "$cur_"))
210+
local c i=0 IFS=$' \t\n'
211+
for c in $1; do
212+
c="$c${4-}"
213+
if [[ $c == "$cur_"* ]]; then
214+
case $c in
215+
--*=*|*.) ;;
216+
*) c="$c " ;;
217+
esac
218+
COMPREPLY[i++]="${2-}$c"
219+
fi
220+
done
218221
;;
219222
esac
220223
}
221224

222-
# Generates completion reply with compgen from newline-separated possible
223-
# completion words by appending a space to all of them.
225+
# Generates completion reply from newline-separated possible completion words
226+
# by appending a space to all of them.
224227
# It accepts 1 to 4 arguments:
225228
# 1: List of possible completion words, separated by a single newline.
226229
# 2: A prefix to be added to each possible completion word (optional).
@@ -231,7 +234,7 @@ __gitcomp ()
231234
__gitcomp_nl ()
232235
{
233236
local IFS=$'\n'
234-
COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}"))
237+
__gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
235238
}
236239

237240
# Generates completion reply with compgen from newline-separated possible
@@ -614,7 +617,6 @@ __git_complete_remote_or_refspec ()
614617
case "$cmd" in
615618
push) no_complete_refspec=1 ;;
616619
fetch)
617-
COMPREPLY=()
618620
return
619621
;;
620622
*) ;;
@@ -630,7 +632,6 @@ __git_complete_remote_or_refspec ()
630632
return
631633
fi
632634
if [ $no_complete_refspec = 1 ]; then
633-
COMPREPLY=()
634635
return
635636
fi
636637
[ "$remote" = "." ] && remote=
@@ -951,7 +952,6 @@ _git_am ()
951952
"
952953
return
953954
esac
954-
COMPREPLY=()
955955
}
956956

957957
_git_apply ()
@@ -971,7 +971,6 @@ _git_apply ()
971971
"
972972
return
973973
esac
974-
COMPREPLY=()
975974
}
976975

977976
_git_add ()
@@ -1031,7 +1030,6 @@ _git_bisect ()
10311030
__gitcomp_nl "$(__git_refs)"
10321031
;;
10331032
*)
1034-
COMPREPLY=()
10351033
;;
10361034
esac
10371035
}
@@ -1124,9 +1122,14 @@ _git_cherry ()
11241122

11251123
_git_cherry_pick ()
11261124
{
1125+
local dir="$(__gitdir)"
1126+
if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
1127+
__gitcomp "--continue --quit --abort"
1128+
return
1129+
fi
11271130
case "$cur" in
11281131
--*)
1129-
__gitcomp "--edit --no-commit"
1132+
__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
11301133
;;
11311134
*)
11321135
__gitcomp_nl "$(__git_refs)"
@@ -1170,7 +1173,6 @@ _git_clone ()
11701173
return
11711174
;;
11721175
esac
1173-
COMPREPLY=()
11741176
}
11751177

11761178
_git_commit ()
@@ -1354,7 +1356,6 @@ _git_fsck ()
13541356
return
13551357
;;
13561358
esac
1357-
COMPREPLY=()
13581359
}
13591360

13601361
_git_gc ()
@@ -1365,7 +1366,6 @@ _git_gc ()
13651366
return
13661367
;;
13671368
esac
1368-
COMPREPLY=()
13691369
}
13701370

13711371
_git_gitk ()
@@ -1442,7 +1442,6 @@ _git_init ()
14421442
return
14431443
;;
14441444
esac
1445-
COMPREPLY=()
14461445
}
14471446

14481447
_git_ls_files ()
@@ -1578,7 +1577,6 @@ _git_mergetool ()
15781577
return
15791578
;;
15801579
esac
1581-
COMPREPLY=()
15821580
}
15831581

15841582
_git_merge_base ()
@@ -1831,7 +1829,7 @@ _git_config ()
18311829
local remote="${prev#remote.}"
18321830
remote="${remote%.fetch}"
18331831
if [ -z "$cur" ]; then
1834-
COMPREPLY=("refs/heads/")
1832+
__gitcompadd "refs/heads/" "" "" ""
18351833
return
18361834
fi
18371835
__gitcomp_nl "$(__git_refs_remotes "$remote")"
@@ -1891,7 +1889,6 @@ _git_config ()
18911889
return
18921890
;;
18931891
*.*)
1894-
COMPREPLY=()
18951892
return
18961893
;;
18971894
esac
@@ -2272,7 +2269,6 @@ _git_remote ()
22722269
__gitcomp "$c"
22732270
;;
22742271
*)
2275-
COMPREPLY=()
22762272
;;
22772273
esac
22782274
}
@@ -2388,8 +2384,6 @@ _git_stash ()
23882384
*)
23892385
if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
23902386
__gitcomp "$subcommands"
2391-
else
2392-
COMPREPLY=()
23932387
fi
23942388
;;
23952389
esac
@@ -2402,14 +2396,12 @@ _git_stash ()
24022396
__gitcomp "--index --quiet"
24032397
;;
24042398
show,--*|drop,--*|branch,--*)
2405-
COMPREPLY=()
24062399
;;
24072400
show,*|apply,*|drop,*|pop,*|branch,*)
24082401
__gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
24092402
| sed -n -e 's/:.*//p')"
24102403
;;
24112404
*)
2412-
COMPREPLY=()
24132405
;;
24142406
esac
24152407
fi
@@ -2526,7 +2518,6 @@ _git_svn ()
25262518
__gitcomp "--revision= --parent"
25272519
;;
25282520
*)
2529-
COMPREPLY=()
25302521
;;
25312522
esac
25322523
fi
@@ -2551,13 +2542,10 @@ _git_tag ()
25512542

25522543
case "$prev" in
25532544
-m|-F)
2554-
COMPREPLY=()
25552545
;;
25562546
-*|tag)
25572547
if [ $f = 1 ]; then
25582548
__gitcomp_nl "$(__git_tags)"
2559-
else
2560-
COMPREPLY=()
25612549
fi
25622550
;;
25632551
*)

t/t9902-completion.sh

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ run_completion ()
6969
local -a COMPREPLY _words
7070
local _cword
7171
_words=( $1 )
72+
test "${1: -1}" == ' ' && _words+=('')
7273
(( _cword = ${#_words[@]} - 1 ))
7374
__git_wrap__git_main && print_comp
7475
}
@@ -104,6 +105,23 @@ test_gitcomp ()
104105
test_cmp expected out
105106
}
106107

108+
# Test __gitcomp_nl
109+
# Arguments are:
110+
# 1: current word (cur)
111+
# -: the rest are passed to __gitcomp_nl
112+
test_gitcomp_nl ()
113+
{
114+
local -a COMPREPLY &&
115+
sed -e 's/Z$//' >expected &&
116+
cur="$1" &&
117+
shift &&
118+
__gitcomp_nl "$@" &&
119+
print_comp &&
120+
test_cmp expected out
121+
}
122+
123+
invalid_variable_name='${foo.bar}'
124+
107125
test_expect_success '__gitcomp - trailing space - options' '
108126
test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
109127
--reset-author" <<-EOF
@@ -147,8 +165,51 @@ test_expect_success '__gitcomp - suffix' '
147165
EOF
148166
'
149167

168+
test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
169+
__gitcomp "$invalid_variable_name"
170+
'
171+
172+
read -r -d "" refs <<-\EOF
173+
maint
174+
master
175+
next
176+
pu
177+
EOF
178+
179+
test_expect_success '__gitcomp_nl - trailing space' '
180+
test_gitcomp_nl "m" "$refs" <<-EOF
181+
maint Z
182+
master Z
183+
EOF
184+
'
185+
186+
test_expect_success '__gitcomp_nl - prefix' '
187+
test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
188+
--fixup=maint Z
189+
--fixup=master Z
190+
EOF
191+
'
192+
193+
test_expect_success '__gitcomp_nl - suffix' '
194+
test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
195+
branch.maint.Z
196+
branch.master.Z
197+
EOF
198+
'
199+
200+
test_expect_success '__gitcomp_nl - no suffix' '
201+
test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
202+
maintZ
203+
masterZ
204+
EOF
205+
'
206+
207+
test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
208+
__gitcomp_nl "$invalid_variable_name"
209+
'
210+
150211
test_expect_success 'basic' '
151-
run_completion "git \"\"" &&
212+
run_completion "git " &&
152213
# built-in
153214
grep -q "^add \$" out &&
154215
# script
@@ -271,7 +332,7 @@ test_expect_success 'complete tree filename with spaces' '
271332
EOF
272333
'
273334

274-
test_expect_failure 'complete tree filename with metacharacters' '
335+
test_expect_success 'complete tree filename with metacharacters' '
275336
echo content >"name with \${meta}" &&
276337
git add . &&
277338
git commit -m meta &&

0 commit comments

Comments
 (0)