Re: [PATCH v2 2/2] completion: add a GIT_COMPLETION_SHOW_ALL_COMMANDS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 02, 2022 at 12:15:10PM +0100, Ævar Arnfjörð Bjarmason wrote:
> Add a GIT_COMPLETION_SHOW_ALL_COMMANDS=1 configuration setting to go
> with the existing GIT_COMPLETION_SHOW_ALL=1 added in
> c099f579b98 (completion: add GIT_COMPLETION_SHOW_ALL env var,
> 2020-08-19).
> 
> This will include plumbing commands such as "cat-file" in "git <TAB>"
> and "git c<TAB>" completion.

I've tried this a couple of times in the last dozen years or so...
and ended up hating it every single time, because it too often made
completion of frequently used porcelain commands more cumbersome, and
quickly reverted it.

Since 6532f3740b (completion: allow to customize the completable
command list, 2018-05-20) it is possible to include and exclude
certain commands from the list offered for 'git <TAB>'.  So if you use
some plumbing command frequently, then you can add them to the
'completion.commands' config variable, and they will show up for 'git
<TAB>', too, without any of the other plumbing commands to get
annoying.

To complete only rarely used plumbing commands in a non-intrusive way,
in my experience, it's best to first attempt to complete only
porcelains and aliases, and fall back to complete all commands,
plumbing included, only when no porcelains match the current word to
be completed.  E.g.:

  $ git d<TAB>
  describe   diff   difftool
  $ git diff-<TAB>
  diff-files   diff-index   diff-tree

  $ git p<TAB>
  prune   pull    push    
  $ git pa<TAB>
  pack-objects     pack-redundant   pack-refs        patch-id 


  ---   >8   ---

Subject: [PATCH] completion: list all git commands as fallback

---
 contrib/completion/git-completion.bash | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 3edd1cade6..67978e6f22 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3465,6 +3465,9 @@ __git_main ()
 				__gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
 			else
 				__gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
+				if [ ${#COMPREPLY[@]} -eq 0 ]; then
+					__gitcomp "$(__git --list-cmds=main,others,nohelpers,alias,list-complete,config)"
+				fi
 			fi
 			;;
 		esac
-- 
2.35.1.482.g3282949ee0

  ---   8<   ---

I've been using 'completion.commands' and the patch above for a few
years now, and this combination worked out the best so far.

> Without/with this I have 134 and 243
> completion with git <TAB>, respectively.

Those numbers include all your aliases and additional 'git-foo'
commands in your PATH; I only get 74 without this patch.  To show the
effect of this patch I think it would be more relevant to count only
Git's commands.


> It was already possible to do this by tweaking
> GIT_TESTING_PORCELAIN_COMMAND_LIST= from the outside, that testing
> variable was added in 84a97131065 (completion: let git provide the
> completable command list, 2018-05-20). Doing this before loading
> git-completion.bash worked:
> 
>     export GIT_TESTING_PORCELAIN_COMMAND_LIST="$(git --list-cmds=builtins,main,list-mainporcelain,others,nohelpers,alias,list-complete,config)"
> 
> But such testing variables are not meant to be used from the outside,
> and we make no guarantees that those internal won't change. So let's
> expose this as a dedicated configuration knob.
> 
> It would be better to teach --list-cmds=* a new category which would
> include all of these groups, but that's a larger change that we can
> leave for some other time.
> 
> 1. https://lore.kernel.org/git/CAGP6POJ9gwp+t-eP3TPkivBLLbNb2+qj=61Mehcj=1BgrVOSLA@xxxxxxxxxxxxxx/
> 
> Reported-by: Hongyi Zhao <hongyi.zhao@xxxxxxxxx>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
> ---
>  contrib/completion/git-completion.bash | 13 ++++++++++-
>  t/t9902-completion.sh                  | 31 ++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+), 1 deletion(-)
> 
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 377d6c5494a..2436b8eb6b9 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -49,6 +49,11 @@
>  #     and git-switch completion (e.g., completing "foo" when "origin/foo"
>  #     exists).
>  #
> +#   GIT_COMPLETION_SHOW_ALL_COMMANDS
> +#
> +#     When set to "1" suggest all commands, including plumbing commands
> +#     which are hidden by default (e.g. "cat-file" on "git ca<TAB>").
> +#
>  #   GIT_COMPLETION_SHOW_ALL
>  #
>  #     When set to "1" suggest all options, including options which are
> @@ -3455,7 +3460,13 @@ __git_main ()
>  			then
>  				__gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
>  			else
> -				__gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
> +				local list_cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
> +
> +				if test "${GIT_COMPLETION_SHOW_ALL_COMMANDS-}" = "1"
> +				then
> +					list_cmds=builtins,$list_cmds
> +				fi
> +				__gitcomp "$(__git --list-cmds=$list_cmds)"
>  			fi
>  			;;
>  		esac
> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
> index c9805f2147d..c6d6d6ef896 100755
> --- a/t/t9902-completion.sh
> +++ b/t/t9902-completion.sh
> @@ -2440,6 +2440,37 @@ test_expect_success 'option aliases are shown with GIT_COMPLETION_SHOW_ALL' '
>  	)
>  '
>  
> +test_expect_success 'plumbing commands are excluded without GIT_COMPLETION_SHOW_ALL_COMMANDS' '
> +	(
> +		. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
> +		sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST &&
> +
> +		# Just mainporcelain, not plumbing commands
> +		run_completion "git c" &&
> +		grep checkout out &&
> +		! grep cat-file out
> +	)
> +'
> +
> +test_expect_success 'all commands are shown with GIT_COMPLETION_SHOW_ALL_COMMANDS (also main non-builtin)' '
> +	(
> +		. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
> +		GIT_COMPLETION_SHOW_ALL_COMMANDS=1 &&
> +		export GIT_COMPLETION_SHOW_ALL_COMMANDS &&

This variable only affects the completion script itself, but none of
the commands invoked by it, so the 'export' is unnecessary.

> +		sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST &&
> +
> +		# Both mainporcelain and plumbing commands
> +		run_completion "git c" &&
> +		grep checkout out &&
> +		grep cat-file out &&
> +
> +		# Check "gitk", a "main" command, but not a built-in + more plumbing
> +		run_completion "git g" &&
> +		grep gitk out &&
> +		grep get-tar-commit-id out
> +	)
> +'
> +
>  test_expect_success '__git_complete' '
>  	unset -f __git_wrap__git_main &&
>  
> -- 
> 2.35.0.913.g12b4baa2536
> 



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux