Subject: [PATCH v2 15/17] completion: add and use --list-cmds=nohelpers

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sun, 20 May 2018 20:40:07 +0200

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 Documentation/git.txt                  |  3 ++-
 contrib/completion/git-completion.bash | 20 ++++----------------
 git.c                                  | 14 ++++++++++++++
 3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index c423810eac..820ab77fcb 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -169,7 +169,8 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
 	groups are: builtins, parseopt (builtin commands that use
 	parse-options), main (all commands in libexec directory),
 	others (all other commands in `$PATH` that have git- prefix),
-	list-<category> (see categories in command-list.txt)
+	list-<category> (see categories in command-list.txt),
+	nohelpers (exclude helper commands).
 
 GIT COMMANDS
 ------------
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index cd1d8e553f..217c8a3d3b 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -843,7 +843,7 @@ __git_commands () {
 		then
 			printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
 		else
-			git --list-cmds=list-mainporcelain,others,list-complete
+			git --list-cmds=list-mainporcelain,others,nohelpers,list-complete
 		fi
 		;;
 	all)
@@ -851,27 +851,15 @@ __git_commands () {
 		then
 			printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST"
 		else
-			git --list-cmds=main,others
+			git --list-cmds=main,others,nohelpers
 		fi
 		;;
 	esac
 }
 
-__git_list_commands ()
-{
-	local i IFS=" "$'\n'
-	for i in $(__git_commands $1)
-	do
-		case $i in
-		*--*)             : helper pattern;;
-		*) echo $i;;
-		esac
-	done
-}
-
 __git_list_all_commands ()
 {
-	__git_list_commands all
+	__git_commands all
 }
 
 __git_all_commands=
@@ -883,7 +871,7 @@ __git_compute_all_commands ()
 
 __git_list_porcelain_commands ()
 {
-	__git_list_commands porcelain
+	__git_commands porcelain
 }
 
 __git_porcelain_commands=
diff --git a/git.c b/git.c
index 19f73b3fa3..f6ae79ffaf 100644
--- a/git.c
+++ b/git.c
@@ -39,6 +39,18 @@ static int use_pager = -1;
 
 static void list_builtins(struct string_list *list, unsigned int exclude_option);
 
+static void exclude_helpers_from_list(struct string_list *list)
+{
+	int i = 0;
+
+	while (i < list->nr) {
+		if (strstr(list->items[i].string, "--"))
+			unsorted_string_list_delete_item(list, i, 0);
+		else
+			i++;
+	}
+}
+
 static int match_token(const char *spec, int len, const char *token)
 {
 	int token_len = strlen(token);
@@ -61,6 +73,8 @@ static int list_cmds(const char *spec)
 			list_all_main_cmds(&list);
 		else if (match_token(spec, len, "others"))
 			list_all_other_cmds(&list);
+		else if (match_token(spec, len, "nohelpers"))
+			exclude_helpers_from_list(&list);
 		else if (len > 5 && !strncmp(spec, "list-", 5)) {
 			struct strbuf sb = STRBUF_INIT;
 
-- 
2.17.0.705.g3525833791