git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
From: Nguyễn Thái Ngọc Duy  <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: Nguyễn Thái Ngọc Duy  <pclouds@gmail.com>
Subject: [PATCH/RFC] completion: complete all possible -no-<options>
Date: Tue, 17 Apr 2018 20:13:00 +0200
Message-ID: <20180417181300.23683-1-pclouds@gmail.com> (raw)

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


             reply index

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-17 18:13 Nguyễn Thái Ngọc Duy [this message]
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

Reply instructions:

You may reply publically 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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=20180417181300.23683-1-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    /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

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