git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Philip Oakley" <philipoakley@iee.email>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>,
	"SZEDER Gábor" <szeder.dev@gmail.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v2 5/5] help / completion: make "git help" do the hard work
Date: Fri, 10 Sep 2021 13:28:46 +0200	[thread overview]
Message-ID: <patch-v2-5.5-e995a42cb8d-20210910T112545Z-avarab@gmail.com> (raw)
In-Reply-To: <cover-v2-0.5-00000000000-20210910T112545Z-avarab@gmail.com>

The "help" builtin has been able to emit configuration variables since
e17ca926371 (completion: drop the hard coded list of config vars,
2018-05-26), but it hasn't produced exactly the format the completion
script wanted. Let's do that.

We got partway there in 2675ea1cc0f (completion: use 'sort -u' to
deduplicate config variable names, 2019-08-13) and
d9438873c4d (completion: deduplicate configuration sections,
2019-08-13), but after both we still needed some sorting,
de-duplicating and awk post-processing of the list.

We can instead simply do the relevant parsing ourselves (we were doing
most of it already), and call string_list_remove_duplicates() after
already sorting the list, so the caller doesn't need to invoke "sort
-u".

This changes the output of the section list to emit lines like "alias"
instead of "alias.". The dot suffix is better done as an argument to
__gitcomp().

This means that we'll have the list_config_help() function do a bit
more work, let's switch its "for_human" to passing a full
"show_config", but as an enum type so we can have the compiler check
what values we're expecting to get.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/help.c                         | 67 ++++++++++++++++++--------
 contrib/completion/git-completion.bash | 21 ++++----
 t/t0012-help.sh                        | 24 +++++++++
 3 files changed, 81 insertions(+), 31 deletions(-)

diff --git a/builtin/help.c b/builtin/help.c
index 05ba2cbe380..9eb09d4804e 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -38,7 +38,12 @@ static const char *html_path;
 
 static int show_all = 0;
 static int show_guides = 0;
-static int show_config;
+enum show_config_type {
+	SHOW_CONFIG_UNSET = 0,
+	SHOW_CONFIG_HUMAN,
+	SHOW_CONFIG_VARS,
+	SHOW_CONFIG_SECTIONS,
+} show_config;
 static int verbose = 1;
 static unsigned int colopts;
 static enum help_format help_format = HELP_FORMAT_NONE;
@@ -48,7 +53,10 @@ static struct option builtin_help_options[] = {
 	OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
 	OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
 	OPT_BOOL('c', "config", &show_config, N_("print all configuration variable names")),
-	OPT_SET_INT_F(0, "config-for-completion", &show_config, "", 2, PARSE_OPT_HIDDEN),
+	OPT_SET_INT_F(0, "config-for-completion-vars", &show_config, "",
+		      SHOW_CONFIG_VARS, PARSE_OPT_HIDDEN),
+	OPT_SET_INT_F(0, "config-for-completion-sections", &show_config, "",
+		      SHOW_CONFIG_SECTIONS, PARSE_OPT_HIDDEN),
 	OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN),
 	OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"),
 			HELP_FORMAT_WEB),
@@ -73,7 +81,7 @@ struct slot_expansion {
 	int found;
 };
 
-static void list_config_help(int for_human)
+static void list_config_help(enum show_config_type type)
 {
 	struct slot_expansion slot_expansions[] = {
 		{ "advice", "*", list_config_advices },
@@ -91,6 +99,8 @@ static void list_config_help(int for_human)
 	const char **p;
 	struct slot_expansion *e;
 	struct string_list keys = STRING_LIST_INIT_DUP;
+	struct string_list keys_uniq = STRING_LIST_INIT_DUP;
+	struct string_list_item *item;
 	int i;
 
 	for (p = config_name_list; *p; p++) {
@@ -121,34 +131,48 @@ static void list_config_help(int for_human)
 	for (i = 0; i < keys.nr; i++) {
 		const char *var = keys.items[i].string;
 		const char *wildcard, *tag, *cut;
+		const char *dot = NULL;
+		struct strbuf sb = STRBUF_INIT;
 
-		if (for_human) {
+		switch (type) {
+		case SHOW_CONFIG_HUMAN:
 			puts(var);
 			continue;
+		case SHOW_CONFIG_SECTIONS:
+			dot = strchr(var, '.');
+			break;
+		case SHOW_CONFIG_VARS:
+			break;
+		case SHOW_CONFIG_UNSET:
+			BUG("should not get SHOW_CONFIG_UNSET here");
 		}
-
 		wildcard = strchr(var, '*');
 		tag = strchr(var, '<');
 
-		if (!wildcard && !tag) {
-			puts(var);
+		if (!dot && !wildcard && !tag) {
+			string_list_append(&keys_uniq, var);
 			continue;
 		}
 
-		if (wildcard && !tag)
+		if (dot)
+			cut = dot;
+		else if (wildcard && !tag)
 			cut = wildcard;
 		else if (!wildcard && tag)
 			cut = tag;
 		else
 			cut = wildcard < tag ? wildcard : tag;
 
-		/*
-		 * We may produce duplicates, but that's up to
-		 * git-completion.bash to handle
-		 */
-		printf("%.*s\n", (int)(cut - var), var);
+		strbuf_add(&sb, var, cut - var);
+		string_list_append(&keys_uniq, sb.buf);
+		strbuf_release(&sb);
+
 	}
 	string_list_clear(&keys, 0);
+	string_list_remove_duplicates(&keys_uniq, 0);
+	for_each_string_list_item(item, &keys_uniq)
+		puts(item->string);
+	string_list_clear(&keys_uniq, 0);
 }
 
 static enum help_format parse_help_format(const char *format)
@@ -595,16 +619,19 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 		return 0;
 	}
 
-	if (show_config) {
-		int for_human = show_config == 1;
+	switch (show_config) {
+	case SHOW_CONFIG_UNSET:
+		break;
+	case SHOW_CONFIG_VARS:
+	case SHOW_CONFIG_SECTIONS:
+		list_config_help(show_config);
 
-		if (!for_human) {
-			list_config_help(for_human);
-			return 0;
-		}
+		return 0;
+	case SHOW_CONFIG_HUMAN:
 		setup_pager();
-		list_config_help(for_human);
+		list_config_help(show_config);
 		printf("\n%s\n", _("'git help config' for more information"));
+
 		return 0;
 	}
 
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 8108eda1e86..19b8a172878 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2503,7 +2503,14 @@ __git_config_vars=
 __git_compute_config_vars ()
 {
 	test -n "$__git_config_vars" ||
-	__git_config_vars="$(git help --config-for-completion | sort -u)"
+	__git_config_vars="$(git help --config-for-completion-vars)"
+}
+
+__git_config_sections=
+__git_compute_config_sections ()
+{
+	test -n "$__git_config_sections" ||
+	__git_config_sections="$(git help --config-for-completion-sections)"
 }
 
 # Completes possible values of various configuration variables.
@@ -2717,16 +2724,8 @@ __git_complete_config_variable_name ()
 		__gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
 		;;
 	*)
-		__git_compute_config_vars
-		__gitcomp "$(echo "$__git_config_vars" |
-				awk -F . '{
-					sections[$1] = 1
-				}
-				END {
-					for (s in sections)
-						print s "."
-				}
-				')" "" "$cur_"
+		__git_compute_config_sections
+		__gitcomp "$__git_config_sections" "" "$cur_" "."
 		;;
 	esac
 }
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index cbc9b64f79f..4405eb6dde5 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -95,6 +95,30 @@ test_expect_success 'git help -c' '
 	test_cmp expect actual
 '
 
+test_expect_success 'git help --config-for-completion-vars' '
+	git help -c >human &&
+	grep -E \
+	     -e "^[^.]+\.[^.]+$" \
+	     -e "^[^.]+\.[^.]+\.[^.]+$" human |
+	     sed -e "s/\*.*//" -e "s/<.*//" |
+	     sort -u >human.munged &&
+
+	git help --config-for-completion-vars >vars &&
+	test_cmp human.munged vars
+'
+
+test_expect_success 'git help --config-for-completion-sections' '
+	git help -c >human &&
+	grep -E \
+	     -e "^[^.]+\.[^.]+$" \
+	     -e "^[^.]+\.[^.]+\.[^.]+$" human |
+	     sed -e "s/\..*//" |
+	     sort -u >human.munged &&
+
+	git help --config-for-completion-sections >sections &&
+	test_cmp human.munged sections
+'
+
 test_expect_success 'generate builtin list' '
 	git --list-cmds=builtins >builtins
 '
-- 
2.33.0.873.g125ff7b9940


  parent reply	other threads:[~2021-09-10 11:30 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-08 15:24 [PATCH 0/6] help: fix usage nits & bugs, completion shellscript->C Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 1/6] help: correct the usage string in -h and documentation Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 2/6] help: correct usage string for "git help --guides" Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 3/6] help tests: add test for --config output Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 4/6] help: refactor "for_human" control flow in cmd_help() Ævar Arnfjörð Bjarmason
2021-09-08 16:41   ` Eric Sunshine
2021-09-08 17:02     ` Junio C Hamano
2021-09-08 19:36       ` Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 5/6] help: correct logic error in combining --all and --config Ævar Arnfjörð Bjarmason
2021-09-08 16:39   ` Eric Sunshine
2021-09-08 19:37     ` Ævar Arnfjörð Bjarmason
2021-09-10  8:08       ` Eric Sunshine
2021-09-10 11:09         ` Ævar Arnfjörð Bjarmason
2021-09-08 15:24 ` [PATCH 6/6] help / completion: make "git help" do the hard work Ævar Arnfjörð Bjarmason
2021-09-10 11:28 ` [PATCH v2 0/5] help: fix usage nits & bugs, completion shellscript->C Ævar Arnfjörð Bjarmason
2021-09-10 11:28   ` [PATCH v2 1/5] help: correct the usage string in -h and documentation Ævar Arnfjörð Bjarmason
2021-09-11  1:12     ` Junio C Hamano
2021-09-11  2:34       ` Ævar Arnfjörð Bjarmason
2021-09-10 11:28   ` [PATCH v2 2/5] help: correct usage & behavior of "git help --guides" Ævar Arnfjörð Bjarmason
2021-09-10 18:15     ` Philip Oakley
2021-09-10 18:21       ` Philip Oakley
2021-09-21 13:49         ` Ævar Arnfjörð Bjarmason
2021-09-21 14:20           ` Philip Oakley
2021-09-11  1:22     ` Junio C Hamano
2021-09-10 11:28   ` [PATCH v2 3/5] help tests: add test for --config output Ævar Arnfjörð Bjarmason
2021-09-11  1:32     ` Junio C Hamano
2021-09-11  2:25       ` Ævar Arnfjörð Bjarmason
2021-09-13 19:21     ` Philip Oakley
2021-09-10 11:28   ` [PATCH v2 4/5] help: correct logic error in combining --all and --config Ævar Arnfjörð Bjarmason
2021-09-10 23:45     ` Junio C Hamano
2021-09-10 11:28   ` Ævar Arnfjörð Bjarmason [this message]
2021-09-11  1:35     ` [PATCH v2 5/5] help / completion: make "git help" do the hard work Junio C Hamano
2021-09-21 22:40   ` [PATCH v3 0/9] help: fix usage nits & bugs, completion shellscript->C Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 1/9] help: correct the usage string in -h and documentation Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 2/9] help: correct usage & behavior of "git help --guides" Ævar Arnfjörð Bjarmason
2021-09-23 18:05       ` Junio C Hamano
2021-09-21 22:40     ` [PATCH v3 3/9] help tests: add test for --config output Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 4/9] help: correct logic error in combining --all and --config Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 5/9] help: correct logic error in combining --all and --guides Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 6/9] help: simplify by moving to OPT_CMDMODE() Ævar Arnfjörð Bjarmason
2021-09-23 18:03       ` Junio C Hamano
2021-09-23 18:05       ` Junio C Hamano
2021-09-21 22:40     ` [PATCH v3 7/9] help tests: test --config-for-completion option & output Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 8/9] help / completion: make "git help" do the hard work Ævar Arnfjörð Bjarmason
2021-09-21 22:40     ` [PATCH v3 9/9] help: move column config discovery to help.c library Ævar Arnfjörð Bjarmason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=patch-v2-5.5-e995a42cb8d-20210910T112545Z-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pclouds@gmail.com \
    --cc=philipoakley@iee.email \
    --cc=sunshine@sunshineco.com \
    --cc=szeder.dev@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).