git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
* [PATCH/RFC] completion: complete all possible -no-<options>
@ 2018-04-17 18:13 Nguyễn Thái Ngọc Duy
  2018-04-18  3:43 ` Junio C Hamano
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2018-04-17 18:13 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

This is not a complete topic but I'd like to present the problem and
my approach to see if it's a good way to go.

We have started recently to rely on parse-options to help complete
options. One of the leftover items is allowing completing --no- form.
This patch enables that (some options should not have --no- form, but
that's easy not included here).

The problem with completing --no- form is that the number of
completable options now usually doubles, taking precious screen space
and also making it hard to find the option you want.

So the other half of this patch, the part in git-completion.bash, is
to uncomplete --no- options. When you do "git checkout --<tab>",
instead of displaying all --no- options, this patch simply displays
one item: the --no- prefix. If you do "git checkout --no-<tab>" then
all negative options are displayed. This helps reduce completable
options quite efficiently.

Of course life is not that simple, we do have --no- options by default
sometimes (taking priority over the positive form), e.g. "git clone
--no-checkout". Collapsing all --no-options into --no- would be a
regression.

To avoid it, the order of options --git-completion-helper returns does
matter. The first 4 negative options are not collapsed. Only options
after the 4th are. Extra --no- options are always printed at the end,
after all the --no- defined in struct option, this kinda works. Not
pretty but works.

After all this "git checkout --<tab>" now looks like this

    > ~/w/git $ git co --
    --conflict=                   --orphan=
    --detach                      --ours 
    --ignore-other-worktrees      --patch 
    --ignore-skip-worktree-bits   --progress 
    --merge                       --quiet 
    --no-                         --recurse-submodules 
    --no-detach                   --theirs 
    --no-quiet                    --track 
    --no-track                    

and all the no options

    > ~/w/git $ git co --no-
    --no-conflict                    --no-patch 
    --no-detach                      --no-progress 
    --no-ignore-other-worktrees      --no-quiet 
    --no-ignore-skip-worktree-bits   --no-recurse-submodules 
    --no-merge                       --no-track 
    --no-orphan                      

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 contrib/completion/git-completion.bash | 25 +++++++++++++++-
 parse-options.c                        | 40 +++++++++++++++++++++++---
 2 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index a757073945..85b9f24465 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -266,7 +266,7 @@ __gitcomp ()
 	case "$cur_" in
 	--*=)
 		;;
-	*)
+	--no-*)
 		local c i=0 IFS=$' \t\n'
 		for c in $1; do
 			c="$c${4-}"
@@ -279,6 +279,29 @@ __gitcomp ()
 			fi
 		done
 		;;
+	*)
+		local c i=0 IFS=$' \t\n' n=0
+		for c in $1; do
+			c="$c${4-}"
+			if [[ $c == "$cur_"* ]]; then
+				case $c in
+				--*=*|*.) ;;
+				--no-*)
+					n=$(($n+1))
+					if [ "$n" -eq 4 ]; then
+						c="--no-${4-} "
+					elif [ "$n" -gt 4 ]; then
+						continue
+					else
+						c="$c "
+					fi
+					;;
+				*) c="$c " ;;
+				esac
+				COMPREPLY[i++]="${2-}$c"
+			fi
+		done
+		;;
 	esac
 }
 
diff --git a/parse-options.c b/parse-options.c
index 0f7059a8ab..f6cd7ca8d2 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -427,13 +427,11 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
 	parse_options_check(options);
 }
 
-/*
- * TODO: we are not completing the --no-XXX form yet because there are
- * many options that do not suppress it properly.
- */
 static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 			const struct option *opts)
 {
+	const struct option *original_opts = opts;
+
 	for (; opts->type != OPTION_END; opts++) {
 		const char *suffix = "";
 
@@ -465,6 +463,40 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 			suffix = "=";
 		printf(" --%s%s", opts->long_name, suffix);
 	}
+	for (opts = original_opts; opts->type != OPTION_END; opts++) {
+		int has_unset_form = 0;
+
+		if (!opts->long_name)
+			continue;
+		if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+			continue;
+		if (opts->flags & PARSE_OPT_NONEG)
+			continue;
+
+		switch (opts->type) {
+		case OPTION_STRING:
+		case OPTION_FILENAME:
+		case OPTION_INTEGER:
+		case OPTION_MAGNITUDE:
+		case OPTION_CALLBACK:
+		case OPTION_BIT:
+		case OPTION_NEGBIT:
+		case OPTION_COUNTUP:
+		case OPTION_SET_INT:
+			has_unset_form = 1;
+			break;
+		default:
+			break;
+		}
+		if (has_unset_form) {
+			const char *name;
+
+			if (skip_prefix(opts->long_name, "no-", &name))
+				printf(" --%s", name);
+			else
+				printf(" --no-%s", opts->long_name);
+		}
+	}
 	fputc('\n', stdout);
 	exit(0);
 }
-- 
2.17.0.367.g5dd2e386c3


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, back to index

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-17 18:13 [PATCH/RFC] completion: complete all possible -no-<options> Nguyễn Thái Ngọc Duy
2018-04-18  3:43 ` Junio C Hamano
2018-04-18 15:08   ` Duy Nguyen
2018-04-23  5:36 ` Eric Sunshine
2018-05-08 15:24   ` Duy Nguyen
2018-05-08 16:39     ` Stefan Beller
2018-05-09  3:20     ` Aaron Schrab
2018-05-14 17:14       ` Duy Nguyen
2018-05-14  3:33     ` Eric Sunshine
2018-05-14 16:39       ` Duy Nguyen
2018-05-14 17:03     ` Andreas Heiduk
2018-05-14 17:26       ` Duy Nguyen
2018-05-14 19:58         ` Andreas Heiduk
2018-05-27  8:38 ` [PATCH v2 0/3] " Nguyễn Thái Ngọc Duy
2018-05-27  8:38   ` [PATCH v2 1/3] parse-options: option to let --git-completion-helper show negative form Nguyễn Thái Ngọc Duy
2018-05-27  8:38   ` [PATCH v2 2/3] completion: suppress some -no- options Nguyễn Thái Ngọc Duy
2018-05-27  8:38   ` [PATCH v2 3/3] completion: collapse extra --no-.. options Nguyễn Thái Ngọc Duy
2018-05-29 18:48     ` Stefan Beller
2018-05-29 19:04       ` Duy Nguyen
2018-06-06  9:41   ` [PATCH v3 0/3] ompletion: complete all possible -no-<options> Nguyễn Thái Ngọc Duy
2018-06-06  9:41     ` [PATCH v3 1/3] parse-options: option to let --git-completion-helper show negative form Nguyễn Thái Ngọc Duy
2018-06-06  9:41     ` [PATCH v3 2/3] completion: suppress some -no- options Nguyễn Thái Ngọc Duy
2018-06-06  9:41     ` [PATCH v3 3/3] completion: collapse extra --no-.. options Nguyễn Thái Ngọc Duy

git@vger.kernel.org list mirror (unofficial, one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox