diff mbox series

[v2] completion: adapt git-config(1) to complete subcommands

Message ID 8d43dee33289969a5afbbf7635ac40b7312d8e19.1715926344.git.ps@pks.im (mailing list archive)
State Accepted
Commit 5dd5007f8936f8d37cf95119e83039bd9237a3c5
Headers show
Series [v2] completion: adapt git-config(1) to complete subcommands | expand

Commit Message

Patrick Steinhardt May 17, 2024, 6:13 a.m. UTC
With fe3ccc7aab (Merge branch 'ps/config-subcommands', 2024-05-15),
git-config(1) has gained support for subcommands. These subcommands live
next to the old, action-based mode, so that both the old and new way
continue to work.

The manpage for this command has been updated to prominently show the
subcommands, and the action-based modes are marked as deprecated. Update
Bash completion scripts accordingly to advertise subcommands instead of
actions.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
Range-diff against v1:
1:  e0039edb9b ! 1:  8d43dee332 completion: adapt git-config(1) to complete subcommands
    @@ contrib/completion/git-completion.bash: __git_complete_config_variable_name_and_
     -	case "$prev" in
     -	--get|--get-all|--unset|--unset-all)
     -		__gitcomp_nl "$(__git_config_get_set_variables)"
    -+	local subcommands="list get set unset rename-section remove-section edit"
    -+	local subcommand="$(__git_find_on_cmdline "$subcommands")"
    ++	local subcommands subcommand
    ++
    ++	__git_resolve_builtins "config"
    ++
    ++	subcommands="$___git_resolved_builtins"
    ++	subcommand="$(__git_find_subcommand "$subcommands")"
     +
     +	if [ -z "$subcommand" ]
     +	then

 contrib/completion/git-completion.bash | 42 ++++++++++++++-----
 t/t9902-completion.sh                  | 56 +++++++++++++++++++-------
 2 files changed, 73 insertions(+), 25 deletions(-)


base-commit: 19fe900cfce8096b7645ec9611a0b981f6bbd154

Comments

Rubén Justo May 17, 2024, 4:27 p.m. UTC | #1
On Fri, May 17, 2024 at 08:13:36AM +0200, Patrick Steinhardt wrote:

>     ++	__git_resolve_builtins "config"

The __git_resolve_builtins() function executes "git config
--git-completion-helper" and caches the result for future calls.  And
on return ...

>     ++
>     ++	subcommands="$___git_resolved_builtins"

... it populates the ___git_resolved_builtins variable with the result:
the available subcommands for "git config".

>     ++	subcommand="$(__git_find_subcommand "$subcommands")"

Then, we look for a subcommand among those returned, at
${words[__git_cmd_idx+1]}, where a possible command must reside.

Nicely done.  This looks good to me.

I wonder, if we might consider the possibility of having "list" as
a default command:

-	subcommand="$(__git_find_subcommand "$subcommands")"
+	subcommand="$(__git_find_subcommand "$subcommands" list)"

These lines are only meant to express the idea, as other changes are
also necessary and the documentation needs to be updated.  Of course, it
could be done in a future series.

I think that "git config -h" is an intuitive enough way to offer the
help text and that using 'git config' as a shortcut for 'git config
list' can be convenient.

By the way, having used '__git_find_subcommand' instead of
'__git_find_on_cmdline' is reassuring when it comes to having a default
subcommand :-)

Anyway, as I said, this series looks good to me.  Thanks!
Patrick Steinhardt May 21, 2024, 6:23 a.m. UTC | #2
On Fri, May 17, 2024 at 06:27:54PM +0200, Rubén Justo wrote:
> On Fri, May 17, 2024 at 08:13:36AM +0200, Patrick Steinhardt wrote:
[snip]
> I wonder, if we might consider the possibility of having "list" as
> a default command:
> 
> -	subcommand="$(__git_find_subcommand "$subcommands")"
> +	subcommand="$(__git_find_subcommand "$subcommands" list)"
> 
> These lines are only meant to express the idea, as other changes are
> also necessary and the documentation needs to be updated.  Of course, it
> could be done in a future series.
> 
> I think that "git config -h" is an intuitive enough way to offer the
> help text and that using 'git config' as a shortcut for 'git config
> list' can be convenient.

Hm. I don't really know whether it is sensible to second-guess what the
user wants to do. They may want to list variables, but they may just as
well not want to do that. I myself use tab completion to learn about
which subcommands exist quite often, even though there is `-h` to do
that for me. So I think I lean more towards not having a default
subcommand here.

> By the way, having used '__git_find_subcommand' instead of
> '__git_find_on_cmdline' is reassuring when it comes to having a default
> subcommand :-)
> 
> Anyway, as I said, this series looks good to me.  Thanks!

Thanks for your review!

Patrick
diff mbox series

Patch

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 5c0ddeb3d4..60a22d619a 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2989,22 +2989,42 @@  __git_complete_config_variable_name_and_value ()
 
 _git_config ()
 {
-	case "$prev" in
-	--get|--get-all|--unset|--unset-all)
-		__gitcomp_nl "$(__git_config_get_set_variables)"
+	local subcommands subcommand
+
+	__git_resolve_builtins "config"
+
+	subcommands="$___git_resolved_builtins"
+	subcommand="$(__git_find_subcommand "$subcommands")"
+
+	if [ -z "$subcommand" ]
+	then
+		__gitcomp "$subcommands"
 		return
-		;;
-	*.*)
-		__git_complete_config_variable_value
+	fi
+
+	case "$cur" in
+	--*)
+		__gitcomp_builtin "config_$subcommand"
 		return
 		;;
 	esac
-	case "$cur" in
-	--*)
-		__gitcomp_builtin config
+
+	case "$subcommand" in
+	get)
+		__gitcomp_nl "$(__git_config_get_set_variables)"
 		;;
-	*)
-		__git_complete_config_variable_name
+	set)
+		case "$prev" in
+		*.*)
+			__git_complete_config_variable_value
+			;;
+		*)
+			__git_complete_config_variable_name
+			;;
+		esac
+		;;
+	unset)
+		__gitcomp_nl "$(__git_config_get_set_variables)"
 		;;
 	esac
 }
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 963f865f27..64c9979423 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2742,30 +2742,58 @@  do
 	'
 done
 
-test_expect_success 'git config - section' '
-	test_completion "git config br" <<-\EOF
+test_expect_success 'git config subcommand' '
+	test_completion "git config " <<-\EOF
+	edit Z
+	get Z
+	list Z
+	remove-section Z
+	rename-section Z
+	set Z
+	unset Z
+	EOF
+'
+
+test_expect_success 'git config subcommand options' '
+	test_completion "git config get --show-" <<-\EOF
+	--show-names Z
+	--show-origin Z
+	--show-scope Z
+	EOF
+'
+
+test_expect_success 'git config get' '
+	test_when_finished "rm -f cfgfile" &&
+	git config set --file cfgfile foo.bar baz &&
+	test_completion "git config get --file cfgfile foo." <<-\EOF
+	foo.bar Z
+	EOF
+'
+
+test_expect_success 'git config set - section' '
+	test_completion "git config set br" <<-\EOF
 	branch.Z
 	browser.Z
 	EOF
 '
 
-test_expect_success 'git config - section include, includeIf' '
-	test_completion "git config inclu" <<-\EOF
+test_expect_success 'git config set - section include, includeIf' '
+	test_completion "git config set inclu" <<-\EOF
 	include.Z
 	includeIf.Z
 	EOF
 '
 
-test_expect_success 'git config - variable name' '
-	test_completion "git config log.d" <<-\EOF
+test_expect_success 'git config set - variable name' '
+	test_completion "git config set log.d" <<-\EOF
 	log.date Z
 	log.decorate Z
 	log.diffMerges Z
 	EOF
 '
 
-test_expect_success 'git config - variable name include' '
-	test_completion "git config include.p" <<-\EOF
+test_expect_success 'git config set - variable name include' '
+	test_completion "git config set include.p" <<-\EOF
 	include.path Z
 	EOF
 '
@@ -2776,8 +2804,8 @@  test_expect_success 'setup for git config submodule tests' '
 	git submodule add ./sub
 '
 
-test_expect_success 'git config - variable name - submodule and __git_compute_first_level_config_vars_for_section' '
-	test_completion "git config submodule." <<-\EOF
+test_expect_success 'git config set - variable name - submodule and __git_compute_first_level_config_vars_for_section' '
+	test_completion "git config set submodule." <<-\EOF
 	submodule.active Z
 	submodule.alternateErrorStrategy Z
 	submodule.alternateLocation Z
@@ -2788,8 +2816,8 @@  test_expect_success 'git config - variable name - submodule and __git_compute_fi
 	EOF
 '
 
-test_expect_success 'git config - variable name - __git_compute_second_level_config_vars_for_section' '
-	test_completion "git config submodule.sub." <<-\EOF
+test_expect_success 'git config set - variable name - __git_compute_second_level_config_vars_for_section' '
+	test_completion "git config set submodule.sub." <<-\EOF
 	submodule.sub.url Z
 	submodule.sub.update Z
 	submodule.sub.branch Z
@@ -2799,8 +2827,8 @@  test_expect_success 'git config - variable name - __git_compute_second_level_con
 	EOF
 '
 
-test_expect_success 'git config - value' '
-	test_completion "git config color.pager " <<-\EOF
+test_expect_success 'git config set - value' '
+	test_completion "git config set color.pager " <<-\EOF
 	false Z
 	true Z
 	EOF