Skip to content

Commit 59d85a2

Browse files
Denton-Lgitster
authored andcommitted
git-completion.bash: use $__git_cmd_idx in more places
With the introduction of the $__git_cmd_idx variable in e94fb44 (git-completion.bash: pass $__git_subcommand_idx from __git_main(), 2021-03-24), completion functions were able to know the index at which the git command is listed, allowing them to skip options that are given to the underlying git itself, not the corresponding command (e.g. `-C asdf` in `git -C asdf branch`). While most of the changes here are self-explanatory, some bear further explanation. For the __git_find_on_cmdline() and __git_find_last_on_cmdline() pair of functions, these functions are only ever called in the context of a git command completion function. These functions will only care about words after the command so we can safely ignore the words before this. For _git_worktree(), this change is technically a no-op (once the __git_find_last_on_cmdline change is also applied). It was in poor style to have hard-coded on the index right after `worktree`. In case `git worktree` were to ever learn to accept options, the current situation would be inflexible. Signed-off-by: Denton Liu <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 87e6297 commit 59d85a2

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

contrib/completion/git-completion.bash

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,8 @@ __git_complete_revlist ()
10061006

10071007
__git_complete_remote_or_refspec ()
10081008
{
1009-
local cur_="$cur" cmd="${words[1]}"
1010-
local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
1009+
local cur_="$cur" cmd="${words[__git_cmd_idx]}"
1010+
local i c=$((__git_cmd_idx+1)) remote="" pfx="" lhs=1 no_complete_refspec=0
10111011
if [ "$cmd" = "remote" ]; then
10121012
((c++))
10131013
fi
@@ -1176,7 +1176,7 @@ __git_aliased_command ()
11761176
# --show-idx: Optionally show the index of the found word in the $words array.
11771177
__git_find_on_cmdline ()
11781178
{
1179-
local word c=1 show_idx
1179+
local word c="$__git_cmd_idx" show_idx
11801180

11811181
while test $# -gt 1; do
11821182
case "$1" in
@@ -1221,7 +1221,7 @@ __git_find_last_on_cmdline ()
12211221
done
12221222
local wordlist="$1"
12231223

1224-
while [ $c -gt 1 ]; do
1224+
while [ $c -gt "$__git_cmd_idx" ]; do
12251225
((c--))
12261226
for word in $wordlist; do
12271227
if [ "$word" = "${words[c]}" ]; then
@@ -1306,7 +1306,7 @@ __git_count_arguments ()
13061306
local word i c=0
13071307

13081308
# Skip "git" (first argument)
1309-
for ((i=1; i < ${#words[@]}; i++)); do
1309+
for ((i="$__git_cmd_idx"; i < ${#words[@]}; i++)); do
13101310
word="${words[i]}"
13111311

13121312
case "$word" in
@@ -1442,7 +1442,7 @@ __git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD
14421442

14431443
_git_branch ()
14441444
{
1445-
local i c=1 only_local_ref="n" has_r="n"
1445+
local i c="$__git_cmd_idx" only_local_ref="n" has_r="n"
14461446

14471447
while [ $c -lt $cword ]; do
14481448
i="${words[c]}"
@@ -2474,7 +2474,7 @@ _git_switch ()
24742474
__git_config_get_set_variables ()
24752475
{
24762476
local prevword word config_file= c=$cword
2477-
while [ $c -gt 1 ]; do
2477+
while [ $c -gt "$__git_cmd_idx" ]; do
24782478
word="${words[c]}"
24792479
case "$word" in
24802480
--system|--global|--local|--file=*)
@@ -3224,7 +3224,7 @@ _git_svn ()
32243224

32253225
_git_tag ()
32263226
{
3227-
local i c=1 f=0
3227+
local i c="$__git_cmd_idx" f=0
32283228
while [ $c -lt $cword ]; do
32293229
i="${words[c]}"
32303230
case "$i" in
@@ -3276,9 +3276,11 @@ __git_complete_worktree_paths ()
32763276
_git_worktree ()
32773277
{
32783278
local subcommands="add list lock move prune remove unlock"
3279-
local subcommand
3279+
local subcommand subcommand_idx
32803280

3281-
subcommand="$(__git_find_on_cmdline "$subcommands")"
3281+
subcommand="$(__git_find_on_cmdline --show-idx "$subcommands")"
3282+
subcommand_idx="${subcommand% *}"
3283+
subcommand="${subcommand#* }"
32823284

32833285
case "$subcommand,$cur" in
32843286
,*)
@@ -3303,7 +3305,7 @@ _git_worktree ()
33033305
# be either the 'add' subcommand, the unstuck
33043306
# argument of an option (e.g. branch for -b|-B), or
33053307
# the path for the new worktree.
3306-
if [ $cword -eq $((__git_cmd_idx+2)) ]; then
3308+
if [ $cword -eq $((subcommand_idx+1)) ]; then
33073309
# Right after the 'add' subcommand: have to
33083310
# complete the path, so fall back to Bash
33093311
# filename completion.
@@ -3327,7 +3329,7 @@ _git_worktree ()
33273329
__git_complete_worktree_paths
33283330
;;
33293331
move,*)
3330-
if [ $cword -eq $((__git_cmd_idx+2)) ]; then
3332+
if [ $cword -eq $((subcommand_idx+1)) ]; then
33313333
# The first parameter must be an existing working
33323334
# tree to be moved.
33333335
__git_complete_worktree_paths

t/t9902-completion.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,7 @@ test_expect_success '__git_find_on_cmdline - single match' '
18791879
(
18801880
words=(git command --opt list) &&
18811881
cword=${#words[@]} &&
1882+
__git_cmd_idx=1 &&
18821883
__git_find_on_cmdline "add list remove" >actual
18831884
) &&
18841885
test_cmp expect actual
@@ -1889,6 +1890,7 @@ test_expect_success '__git_find_on_cmdline - multiple matches' '
18891890
(
18901891
words=(git command -o --opt remove list add) &&
18911892
cword=${#words[@]} &&
1893+
__git_cmd_idx=1 &&
18921894
__git_find_on_cmdline "add list remove" >actual
18931895
) &&
18941896
test_cmp expect actual
@@ -1898,6 +1900,7 @@ test_expect_success '__git_find_on_cmdline - no match' '
18981900
(
18991901
words=(git command --opt branch) &&
19001902
cword=${#words[@]} &&
1903+
__git_cmd_idx=1 &&
19011904
__git_find_on_cmdline "add list remove" >actual
19021905
) &&
19031906
test_must_be_empty actual
@@ -1908,6 +1911,7 @@ test_expect_success '__git_find_on_cmdline - single match with index' '
19081911
(
19091912
words=(git command --opt list) &&
19101913
cword=${#words[@]} &&
1914+
__git_cmd_idx=1 &&
19111915
__git_find_on_cmdline --show-idx "add list remove" >actual
19121916
) &&
19131917
test_cmp expect actual
@@ -1918,6 +1922,7 @@ test_expect_success '__git_find_on_cmdline - multiple matches with index' '
19181922
(
19191923
words=(git command -o --opt remove list add) &&
19201924
cword=${#words[@]} &&
1925+
__git_cmd_idx=1 &&
19211926
__git_find_on_cmdline --show-idx "add list remove" >actual
19221927
) &&
19231928
test_cmp expect actual
@@ -1927,11 +1932,23 @@ test_expect_success '__git_find_on_cmdline - no match with index' '
19271932
(
19281933
words=(git command --opt branch) &&
19291934
cword=${#words[@]} &&
1935+
__git_cmd_idx=1 &&
19301936
__git_find_on_cmdline --show-idx "add list remove" >actual
19311937
) &&
19321938
test_must_be_empty actual
19331939
'
19341940

1941+
test_expect_success '__git_find_on_cmdline - ignores matches before command with index' '
1942+
echo "6 remove" >expect &&
1943+
(
1944+
words=(git -C remove command -o --opt remove list add) &&
1945+
cword=${#words[@]} &&
1946+
__git_cmd_idx=3 &&
1947+
__git_find_on_cmdline --show-idx "add list remove" >actual
1948+
) &&
1949+
test_cmp expect actual
1950+
'
1951+
19351952
test_expect_success '__git_get_config_variables' '
19361953
cat >expect <<-EOF &&
19371954
name-1
@@ -2275,6 +2292,7 @@ do
22752292
(
22762293
words=(git push '$flag' other ma) &&
22772294
cword=${#words[@]} cur=${words[cword-1]} &&
2295+
__git_cmd_idx=1 &&
22782296
__git_complete_remote_or_refspec &&
22792297
print_comp
22802298
) &&
@@ -2288,6 +2306,7 @@ do
22882306
(
22892307
words=(git push other '$flag' ma) &&
22902308
cword=${#words[@]} cur=${words[cword-1]} &&
2309+
__git_cmd_idx=1 &&
22912310
__git_complete_remote_or_refspec &&
22922311
print_comp
22932312
) &&

0 commit comments

Comments
 (0)