All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.