completion: wrap __git_refs() for better option parsing
__git_refs() currently accepts two optional positional parameters: a remote and a flag for 'git checkout's tracking DWIMery. To fix a minor bug, and, more importantly, for faster refs completion, this series will add three more parameters: a prefix, the current word to be completed and a suffix, i.e. the options accepted by __gitcomp() & friends, and will change __git_refs() to list only refs matching that given current word and to add that given prefix and suffix to the listed refs. However, __git_refs() is the helper function that is most likely used in users' custom completion scriptlets for their own git commands, and we don't want to break those, so - we can't change __git_refs()'s default output format, i.e. we can't by default append a trailing space to every listed ref, meaning that the suffix parameter containing the default trailing space would have to be specified on every invocation, and - we can't change the position of existing positional parameters either, so there would have to be plenty of set-but-empty placeholder positional parameters all over the completion script. Furthermore, with five positional parameters it would be really hard to remember which position means what. To keep callsites simple, add the new wrapper function __git_complete_refs() around __git_refs(), which: - instead of positional parameters accepts real '--opt=val'-style options and with minimalistic option parsing translates them to __git_refs()'s and __gitcomp_nl()'s positional parameters, and - includes the '__gitcomp_nl "$(__git_refs ...)" ...' command substitution to make its behavior match its name and the behavior of other __git_complete_* functions, and to limit future changes in this series to __git_refs() and this new wrapper function. Call this wrapper function instead of __git_refs() wherever possible throughout the completion script, i.e. when __git_refs()'s output is fed to __gitcomp_nl() right away without further processing, which means all callsites except a single one in the __git_refs2() helper. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c977eefd55
commit
15b4a16395
@ -354,6 +354,8 @@ __git_tags ()
|
|||||||
# Can be the name of a configured remote, a path, or a URL.
|
# Can be the name of a configured remote, a path, or a URL.
|
||||||
# 2: In addition to local refs, list unique branches from refs/remotes/ for
|
# 2: In addition to local refs, list unique branches from refs/remotes/ for
|
||||||
# 'git checkout's tracking DWIMery (optional; ignored, if set but empty).
|
# 'git checkout's tracking DWIMery (optional; ignored, if set but empty).
|
||||||
|
#
|
||||||
|
# Use __git_complete_refs() instead.
|
||||||
__git_refs ()
|
__git_refs ()
|
||||||
{
|
{
|
||||||
local i hash dir track="${2-}"
|
local i hash dir track="${2-}"
|
||||||
@ -446,6 +448,36 @@ __git_refs ()
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Completes refs, short and long, local and remote, symbolic and pseudo.
|
||||||
|
#
|
||||||
|
# Usage: __git_complete_refs [<option>]...
|
||||||
|
# --remote=<remote>: The remote to list refs from, can be the name of a
|
||||||
|
# configured remote, a path, or a URL.
|
||||||
|
# --track: List unique remote branches for 'git checkout's tracking DWIMery.
|
||||||
|
# --pfx=<prefix>: A prefix to be added to each ref.
|
||||||
|
# --cur=<word>: The current ref to be completed. Defaults to the current
|
||||||
|
# word to be completed.
|
||||||
|
# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
|
||||||
|
# space.
|
||||||
|
__git_complete_refs ()
|
||||||
|
{
|
||||||
|
local remote track pfx cur_="$cur" sfx=" "
|
||||||
|
|
||||||
|
while test $# != 0; do
|
||||||
|
case "$1" in
|
||||||
|
--remote=*) remote="${1##--remote=}" ;;
|
||||||
|
--track) track="yes" ;;
|
||||||
|
--pfx=*) pfx="${1##--pfx=}" ;;
|
||||||
|
--cur=*) cur_="${1##--cur=}" ;;
|
||||||
|
--sfx=*) sfx="${1##--sfx=}" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
__gitcomp_nl "$(__git_refs "$remote" "$track")" "$pfx" "$cur_" "$sfx"
|
||||||
|
}
|
||||||
|
|
||||||
# __git_refs2 requires 1 argument (to pass to __git_refs)
|
# __git_refs2 requires 1 argument (to pass to __git_refs)
|
||||||
__git_refs2 ()
|
__git_refs2 ()
|
||||||
{
|
{
|
||||||
@ -554,15 +586,15 @@ __git_complete_revlist_file ()
|
|||||||
*...*)
|
*...*)
|
||||||
pfx="${cur_%...*}..."
|
pfx="${cur_%...*}..."
|
||||||
cur_="${cur_#*...}"
|
cur_="${cur_#*...}"
|
||||||
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
|
__git_complete_refs --pfx="$pfx" --cur="$cur_"
|
||||||
;;
|
;;
|
||||||
*..*)
|
*..*)
|
||||||
pfx="${cur_%..*}.."
|
pfx="${cur_%..*}.."
|
||||||
cur_="${cur_#*..}"
|
cur_="${cur_#*..}"
|
||||||
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
|
__git_complete_refs --pfx="$pfx" --cur="$cur_"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -649,21 +681,21 @@ __git_complete_remote_or_refspec ()
|
|||||||
if [ $lhs = 1 ]; then
|
if [ $lhs = 1 ]; then
|
||||||
__gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
|
__gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
|
__git_complete_refs --pfx="$pfx" --cur="$cur_"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
pull|remote)
|
pull|remote)
|
||||||
if [ $lhs = 1 ]; then
|
if [ $lhs = 1 ]; then
|
||||||
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
|
__git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
|
__git_complete_refs --pfx="$pfx" --cur="$cur_"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
push)
|
push)
|
||||||
if [ $lhs = 1 ]; then
|
if [ $lhs = 1 ]; then
|
||||||
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
|
__git_complete_refs --pfx="$pfx" --cur="$cur_"
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
|
__git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1061,7 +1093,7 @@ _git_bisect ()
|
|||||||
|
|
||||||
case "$subcommand" in
|
case "$subcommand" in
|
||||||
bad|good|reset|skip|start)
|
bad|good|reset|skip|start)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
;;
|
;;
|
||||||
@ -1083,7 +1115,7 @@ _git_branch ()
|
|||||||
|
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--set-upstream-to=*)
|
--set-upstream-to=*)
|
||||||
__gitcomp_nl "$(__git_refs)" "" "${cur##--set-upstream-to=}"
|
__git_complete_refs --cur="${cur##--set-upstream-to=}"
|
||||||
;;
|
;;
|
||||||
--*)
|
--*)
|
||||||
__gitcomp "
|
__gitcomp "
|
||||||
@ -1097,7 +1129,7 @@ _git_branch ()
|
|||||||
if [ $only_local_ref = "y" -a $has_r = "n" ]; then
|
if [ $only_local_ref = "y" -a $has_r = "n" ]; then
|
||||||
__gitcomp_nl "$(__git_heads)"
|
__gitcomp_nl "$(__git_heads)"
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1140,18 +1172,18 @@ _git_checkout ()
|
|||||||
*)
|
*)
|
||||||
# check if --track, --no-track, or --no-guess was specified
|
# check if --track, --no-track, or --no-guess was specified
|
||||||
# if so, disable DWIM mode
|
# if so, disable DWIM mode
|
||||||
local flags="--track --no-track --no-guess" track=1
|
local flags="--track --no-track --no-guess" track_opt="--track"
|
||||||
if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
|
if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
|
||||||
track=''
|
track_opt=''
|
||||||
fi
|
fi
|
||||||
__gitcomp_nl "$(__git_refs '' $track)"
|
__git_complete_refs $track_opt
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_cherry ()
|
_git_cherry ()
|
||||||
{
|
{
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_cherry_pick ()
|
_git_cherry_pick ()
|
||||||
@ -1166,7 +1198,7 @@ _git_cherry_pick ()
|
|||||||
__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
|
__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -1216,7 +1248,7 @@ _git_commit ()
|
|||||||
{
|
{
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
-c|-C)
|
-c|-C)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1229,7 +1261,7 @@ _git_commit ()
|
|||||||
;;
|
;;
|
||||||
--reuse-message=*|--reedit-message=*|\
|
--reuse-message=*|--reedit-message=*|\
|
||||||
--fixup=*|--squash=*)
|
--fixup=*|--squash=*)
|
||||||
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
|
__git_complete_refs --cur="${cur#*=}"
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--untracked-files=*)
|
--untracked-files=*)
|
||||||
@ -1267,7 +1299,7 @@ _git_describe ()
|
|||||||
"
|
"
|
||||||
return
|
return
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
__git_diff_algorithms="myers minimal patience histogram"
|
__git_diff_algorithms="myers minimal patience histogram"
|
||||||
@ -1453,7 +1485,7 @@ _git_grep ()
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_help ()
|
_git_help ()
|
||||||
@ -1621,7 +1653,7 @@ _git_merge ()
|
|||||||
--rerere-autoupdate --no-rerere-autoupdate --abort --continue"
|
--rerere-autoupdate --no-rerere-autoupdate --abort --continue"
|
||||||
return
|
return
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_mergetool ()
|
_git_mergetool ()
|
||||||
@ -1646,7 +1678,7 @@ _git_merge_base ()
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_mv ()
|
_git_mv ()
|
||||||
@ -1684,7 +1716,7 @@ _git_notes ()
|
|||||||
,*)
|
,*)
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
--ref)
|
--ref)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp "$subcommands --ref"
|
__gitcomp "$subcommands --ref"
|
||||||
@ -1693,7 +1725,7 @@ _git_notes ()
|
|||||||
;;
|
;;
|
||||||
add,--reuse-message=*|append,--reuse-message=*|\
|
add,--reuse-message=*|append,--reuse-message=*|\
|
||||||
add,--reedit-message=*|append,--reedit-message=*)
|
add,--reedit-message=*|append,--reedit-message=*)
|
||||||
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
|
__git_complete_refs --cur="${cur#*=}"
|
||||||
;;
|
;;
|
||||||
add,--*|append,--*)
|
add,--*|append,--*)
|
||||||
__gitcomp '--file= --message= --reedit-message=
|
__gitcomp '--file= --message= --reedit-message=
|
||||||
@ -1712,7 +1744,7 @@ _git_notes ()
|
|||||||
-m|-F)
|
-m|-F)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@ -1750,10 +1782,10 @@ __git_complete_force_with_lease ()
|
|||||||
--*=)
|
--*=)
|
||||||
;;
|
;;
|
||||||
*:*)
|
*:*)
|
||||||
__gitcomp_nl "$(__git_refs)" "" "${cur_#*:}"
|
__git_complete_refs --cur="${cur_#*:}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp_nl "$(__git_refs)" "" "$cur_"
|
__git_complete_refs --cur="$cur_"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -1829,7 +1861,7 @@ _git_rebase ()
|
|||||||
|
|
||||||
return
|
return
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_reflog ()
|
_git_reflog ()
|
||||||
@ -1840,7 +1872,7 @@ _git_reflog ()
|
|||||||
if [ -z "$subcommand" ]; then
|
if [ -z "$subcommand" ]; then
|
||||||
__gitcomp "$subcommands"
|
__gitcomp "$subcommands"
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1986,7 +2018,7 @@ _git_config ()
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
branch.*.merge)
|
branch.*.merge)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
branch.*.rebase)
|
branch.*.rebase)
|
||||||
@ -2460,7 +2492,7 @@ _git_remote ()
|
|||||||
|
|
||||||
_git_replace ()
|
_git_replace ()
|
||||||
{
|
{
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_reset ()
|
_git_reset ()
|
||||||
@ -2473,7 +2505,7 @@ _git_reset ()
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_revert ()
|
_git_revert ()
|
||||||
@ -2489,7 +2521,7 @@ _git_revert ()
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_rm ()
|
_git_rm ()
|
||||||
@ -2597,7 +2629,7 @@ _git_stash ()
|
|||||||
;;
|
;;
|
||||||
branch,*)
|
branch,*)
|
||||||
if [ $cword -eq 3 ]; then
|
if [ $cword -eq 3 ]; then
|
||||||
__gitcomp_nl "$(__git_refs)";
|
__git_complete_refs
|
||||||
else
|
else
|
||||||
__gitcomp_nl "$(__git stash list \
|
__gitcomp_nl "$(__git stash list \
|
||||||
| sed -n -e 's/:.*//p')"
|
| sed -n -e 's/:.*//p')"
|
||||||
@ -2755,7 +2787,7 @@ _git_tag ()
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
__gitcomp_nl "$(__git_refs)"
|
__git_complete_refs
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -775,6 +775,112 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer
|
|||||||
test_cmp expected "$actual"
|
test_cmp expected "$actual"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - simple' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
HEAD Z
|
||||||
|
master Z
|
||||||
|
matching-branch Z
|
||||||
|
other/branch-in-other Z
|
||||||
|
other/master-in-other Z
|
||||||
|
matching-tag Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur= &&
|
||||||
|
__git_complete_refs &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - matching' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
matching-branch Z
|
||||||
|
matching-tag Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur=mat &&
|
||||||
|
__git_complete_refs &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - remote' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
HEAD Z
|
||||||
|
branch-in-other Z
|
||||||
|
master-in-other Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur=
|
||||||
|
__git_complete_refs --remote=other &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - track' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
HEAD Z
|
||||||
|
master Z
|
||||||
|
matching-branch Z
|
||||||
|
other/branch-in-other Z
|
||||||
|
other/master-in-other Z
|
||||||
|
matching-tag Z
|
||||||
|
branch-in-other Z
|
||||||
|
master-in-other Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur=
|
||||||
|
__git_complete_refs --track &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - current word' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
matching-branch Z
|
||||||
|
matching-tag Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur="--option=mat" &&
|
||||||
|
__git_complete_refs --cur="${cur#*=}" &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - prefix' '
|
||||||
|
sed -e "s/Z$//" >expected <<-EOF &&
|
||||||
|
v1.0..matching-branch Z
|
||||||
|
v1.0..matching-tag Z
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur=v1.0..mat &&
|
||||||
|
__git_complete_refs --pfx=v1.0.. --cur=mat &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '__git_complete_refs - suffix' '
|
||||||
|
cat >expected <<-EOF &&
|
||||||
|
HEAD.
|
||||||
|
master.
|
||||||
|
matching-branch.
|
||||||
|
other/branch-in-other.
|
||||||
|
other/master-in-other.
|
||||||
|
matching-tag.
|
||||||
|
EOF
|
||||||
|
(
|
||||||
|
cur= &&
|
||||||
|
__git_complete_refs --sfx=. &&
|
||||||
|
print_comp
|
||||||
|
) &&
|
||||||
|
test_cmp expected out
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'teardown after ref completion' '
|
test_expect_success 'teardown after ref completion' '
|
||||||
git branch -d matching-branch &&
|
git branch -d matching-branch &&
|
||||||
git tag -d matching-tag &&
|
git tag -d matching-tag &&
|
||||||
|
Loading…
Reference in New Issue
Block a user