Subject: Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Fri, 09 Feb 2018 15:19:57 +0100

On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy jotted:

> By default, some option names (mostly --force, scripting related or for
> internal use) are not completable for various reasons. When
> GIT_COMPLETION_OPTIONS is set to all, all options (except hidden ones)
> are completable.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
> ---
>  contrib/completion/git-completion.bash |  6 +++++-
>  parse-options.c                        | 11 +++++++----
>  2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 0ddf40063b..0cfa489a8e 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -36,6 +36,10 @@
>  #
>  #     When set to "1", do not include "DWIM" suggestions in git-checkout
>  #     completion (e.g., completing "foo" when "origin/foo" exists).
> +#
> +#   GIT_COMPLETION_OPTIONS
> +#
> +#     When set to "all", complete all possible options

I was going to suggest some wording like:

    When set to "all", include options considered unsafe such as --force
    in the completion.

However per your cover letter it's not just used for that:

     10 --force
      4 --rerere-autoupdate
      1 --unsafe-paths
      1 --thin
      1 --overwrite-ignore
      1 --open-files-in-pager
      1 --null
      1 --ext-grep
      1 --exit-code
      1 --auto

I wonder if we shouldn't just make this only about --force, I don't see
why "git grep --o<TAB>" should only show --or but not
--open-files-in-pager, and e.g. "git grep --<TAB>" is already verbose so
we're not saving much by excluding those.

Then this could just become:

    GIT_COMPLETION_SHOWUNSAFEOPTIONS=1

Or other similar boolean variable, for consistency with all the "*SHOW*
variables already in git-completion.bash.

>  case "$COMP_WORDBREAKS" in
>  *:*) : great ;;
> @@ -303,7 +307,7 @@ __gitcomp_builtin ()
>  	if [ -z "$options" ]; then
>  		# leading and trailing spaces are significant to make
>  		# option removal work correctly.
> -		options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
> +		options=" $(__git ${cmd/_/ } --git-completion-helper=$GIT_COMPLETION_OPTIONS) $incl "
>  		for i in $excl; do
>  			options="${options/ $i / }"
>  		done
> diff --git a/parse-options.c b/parse-options.c
> index 979577ba2c..5b8b2b376e 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -430,14 +430,17 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
>   * 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 *opts,
> +			const char *arg)
>  {
>  	for (; opts->type != OPTION_END; opts++) {
>  		const char *suffix = "";
>
>  		if (!opts->long_name)
>  			continue;
> -		if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
> +		if (opts->flags & PARSE_OPT_HIDDEN)
> +			continue;
> +		if ((opts->flags & PARSE_OPT_NOCOMPLETE) && strcmp(arg, "all"))
>  			continue;
>
>  		switch (opts->type) {
> @@ -498,8 +501,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
>  			goto show_usage;
>
>  		/* lone --git-completion-helper is asked by git-completion.bash */
> -		if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
> -			return show_gitcomp(ctx, options);
> +		if (ctx->total == 1 && skip_prefix(arg + 1, "-git-completion-helper=", &arg))
> +			return show_gitcomp(ctx, options, arg);
>
>  		if (arg[1] != '-') {
>  			ctx->opt = arg + 1;