zsh-workers
 help / color / mirror / Atom feed
* [RFC/PATCH] completion: git: add fast mode
@ 2020-11-23 17:56 Felipe Contreras
  2020-11-25  0:19 ` Daniel Shahaf
  2020-11-25 14:48 ` Eric Cook
  0 siblings, 2 replies; 7+ messages in thread
From: Felipe Contreras @ 2020-11-23 17:56 UTC (permalink / raw)
  To: zsh-workers; +Cc: Daniel Shahaf, Felipe Contreras

Using the official Git Bash completion script the completion is
blazingly fast.

We can optionally enable this mode if Git's official Bash completion script is
specified by the user.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---

This patch is just to show how merging the gitfast/git zsh
wrapper/git-completion might look like.

 Completion/Unix/Command/_git | 125 +++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 81a060e4d..9a307faad 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -39,6 +39,104 @@
 
 # TODO: There is still undocumented configurability in here.
 
+zstyle -s ":completion:*:*:git:*" bash-script git_bash_script
+
+if [ -n "$git_bash_script" ]; then
+
+local old_complete="$functions[complete]"
+functions[complete]=:
+COMP_WORDBREAKS=':'
+GIT_SOURCING_ZSH_COMPLETION=y . "$git_bash_script"
+functions[complete]="$old_complete"
+
+__gitcompadd ()
+{
+	compadd -Q -p "${2-}" -S "${3- }" ${@[4,-1]} -- ${=1} && _ret=0
+}
+
+__gitcomp ()
+{
+	emulate -L zsh
+
+	local cur_="${3-$cur}"
+
+	[[ "$cur_" == *= ]] && return
+
+	local c IFS=$' \t\n' sfx
+	for c in ${=1}; do
+		if [[ $c == "--" ]]; then
+			[[ "$cur_" == --no-* ]] && continue
+			__gitcompadd "--no-..."
+			break
+		fi
+
+		if [[ -z "${4-}" ]]; then
+			case $c in
+			*=) c="${c%=}"; sfx="=" ;;
+			*.) sfx="" ;;
+			*) sfx=" " ;;
+			esac
+		else
+			sfx="$4"
+		fi
+		__gitcompadd "$c" "${2-}" "$sfx" -q
+	done
+}
+
+__gitcomp_nl ()
+{
+	emulate -L zsh
+
+	IFS=$'\n' __gitcompadd "$1" "${2-}" "${4- }"
+}
+
+__gitcomp_file ()
+{
+	emulate -L zsh
+
+	compadd -f -p "${2-}" -- ${(f)1} && _ret=0
+}
+
+__gitcomp_direct ()
+{
+	__gitcomp_nl "$1" "" "" ""
+}
+
+__gitcomp_file_direct ()
+{
+	__gitcomp_file "$1" ""
+}
+
+__gitcomp_nl_append ()
+{
+	__gitcomp_nl "$@"
+}
+
+__gitcomp_direct_append ()
+{
+	__gitcomp_direct "$@"
+}
+
+__gitbash_complete_func ()
+{
+	local _ret=1
+	local cur cword prev
+
+	cur=${words[CURRENT]}
+	prev=${words[CURRENT-1]}
+	let cword=CURRENT-1
+
+	if (( $+functions[$1] )); then
+		compset -P '*[=:]'
+		emulate ksh -c $1
+		return _ret
+	else
+		return 1
+	fi
+}
+
+fi
+
 # HIGH-LEVEL COMMANDS (PORCELAIN)
 
 # Main Porcelain Commands
@@ -768,6 +866,11 @@ _git-diff () {
 
   case $state in
     (from-to-file)
+      if [ -n "$git_bash_script" ]; then
+        __gitbash_complete_func __git_complete_revlist && ret=0
+        return ret
+      fi
+
       # If "--" is part of $opt_args, this means it was specified before any
       # $words arguments. This means that no heads are specified in front, so
       # we need to complete *changed* files only.
@@ -953,6 +1056,11 @@ _git-format-patch () {
 
   case $state in
     (commit-or-commit-range)
+      if [ -n "$git_bash_script" ]; then
+        __gitbash_complete_func __git_complete_revlist && ret=0
+        return ret
+      fi
+
       if [[ -n ${opt_args[(I)--root]} ]]; then
         __git_commits && ret=0
       else
@@ -1183,6 +1291,13 @@ _git-log () {
     '1: :->first-commit-ranges-or-files' \
     '*: :->commit-ranges-or-files' && ret=0
 
+  if [ -n "$git_bash_script" ]; then
+    if [ -n "$state" ]; then
+      __gitbash_complete_func __git_complete_revlist && ret=0
+      return ret
+    fi
+  fi
+
   case $state in
     (first-commit-ranges-or-files)
       if [[ -n ${opt_args[(I)--]} ]]; then
@@ -1676,6 +1791,11 @@ _git-shortlog () {
       fi
       ;;
     (commit-range-or-file)
+      if [ -n "$git_bash_script" ]; then
+        __gitbash_complete_func __git_complete_revlist && ret=0
+        return ret
+      fi
+
       case $CURRENT in
         (1)
           if [[ -n ${opt_args[(I)--]} ]]; then
@@ -5412,6 +5532,11 @@ _git-rev-list () {
 
   case $state in
     (commit-or-path)
+      if [ -n "$git_bash_script" ]; then
+        __gitbash_complete_func __git_complete_revlist && ret=0
+        return ret
+      fi
+
       # TODO: What paths should we be completing here?
       if [[ -n ${opt_args[(I)--]} ]]; then
         __git_cached_files && ret=0
-- 
2.29.2



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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-23 17:56 [RFC/PATCH] completion: git: add fast mode Felipe Contreras
@ 2020-11-25  0:19 ` Daniel Shahaf
  2020-11-25  3:54   ` Felipe Contreras
  2020-11-25 14:48 ` Eric Cook
  1 sibling, 1 reply; 7+ messages in thread
From: Daniel Shahaf @ 2020-11-25  0:19 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: zsh-workers

Please state the copyright licenses of the patch and of $git_bash_script.


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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-25  0:19 ` Daniel Shahaf
@ 2020-11-25  3:54   ` Felipe Contreras
  0 siblings, 0 replies; 7+ messages in thread
From: Felipe Contreras @ 2020-11-25  3:54 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Zsh hackers list

On Tue, Nov 24, 2020 at 6:19 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Please state the copyright licenses of the patch and of $git_bash_script.

It is my code. If I wasn't content with the license of the Zsh
project, I wouldn't be proposing my code for contribution.

You can find the licence of the Git bash script on the script itself:

/usr/share/bash-completion/completions/git

Or online:

https://git.kernel.org/pub/scm/git/git.git/tree/contrib/completion/git-completion.bash

Cheers

-- 
Felipe Contreras


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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-23 17:56 [RFC/PATCH] completion: git: add fast mode Felipe Contreras
  2020-11-25  0:19 ` Daniel Shahaf
@ 2020-11-25 14:48 ` Eric Cook
  2020-11-25 22:34   ` Felipe Contreras
  1 sibling, 1 reply; 7+ messages in thread
From: Eric Cook @ 2020-11-25 14:48 UTC (permalink / raw)
  To: zsh-workers

On 11/23/20 12:56 PM, Felipe Contreras wrote:
> This patch is just to show how merging the gitfast/git zsh
> wrapper/git-completion might look like.

Would the overall end goal be to merge the feature set of the two
completers or just allow the two to be used in tandem? The patch
looks like the latter not the former and if so, is a precedent i
would like zsh to not set personally.


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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-25 14:48 ` Eric Cook
@ 2020-11-25 22:34   ` Felipe Contreras
  2020-11-25 22:56     ` Eric Cook
  0 siblings, 1 reply; 7+ messages in thread
From: Felipe Contreras @ 2020-11-25 22:34 UTC (permalink / raw)
  To: Eric Cook; +Cc: Zsh hackers list

On Wed, Nov 25, 2020 at 8:48 AM Eric Cook <llua@gmx.com> wrote:
>
> On 11/23/20 12:56 PM, Felipe Contreras wrote:
> > This patch is just to show how merging the gitfast/git zsh
> > wrapper/git-completion might look like.
>
> Would the overall end goal be to merge the feature set of the two
> completers or just allow the two to be used in tandem? The patch
> looks like the latter not the former and if so, is a precedent i
> would like zsh to not set personally.

I think the overall end goal would be to move as much as possible of
the completion to the Git project itself. For example; git commands
have the --git-completion-helper option, which throw something like:

  % git version --git-completion-helper
  --build-options --no-build-options

There is no _git_version() specific function in Git's bash completion,
and yet when you type "git version --<tab>" the options are completed
anyway.

This helps so that new commands get some automatic completion, even
when nothing specific for them is done in the completion script.

It has been discussed in the mailing list to add something similar for
zsh specific completion, so the descriptions are generated too, and
shorthand forms, perhaps with --git-completion-helper=zsh.

This is a lot of work, and it's unclear precisely how Zsh's official
completion could leverage it, but I think it should be doable.

As for the bulk of the code (e.g. __git_complete_revlist), I think the
end goal should be to borrow the way in which Git developers
themselves leverage the power of Git to generate completions, and use
that in the official completion, perhaps with a "fast-mode" zstyle.

There probably shouldn't be any need to source Git's bash completion
script in the end.

But *today*, the people that want a limble fast completion need to use
that script one way or the other.

I see no way around that.

Cheers.

-- 
Felipe Contreras



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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-25 22:34   ` Felipe Contreras
@ 2020-11-25 22:56     ` Eric Cook
  2020-11-26  0:22       ` Felipe Contreras
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Cook @ 2020-11-25 22:56 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh hackers list

On 11/25/20 5:34 PM, Felipe Contreras wrote:
> I think the overall end goal would be to move as much as possible of
> the completion to the Git project itself. For example; git commands
> have the --git-completion-helper option, which throw something like:
>
>    % git version --git-completion-helper
>    --build-options --no-build-options
>
> There is no _git_version() specific function in Git's bash completion,
> and yet when you type "git version --<tab>" the options are completed
> anyway.
>
> This helps so that new commands get some automatic completion, even
> when nothing specific for them is done in the completion script.
>
> It has been discussed in the mailing list to add something similar for
> zsh specific completion, so the descriptions are generated too, and
> shorthand forms, perhaps with --git-completion-helper=zsh.

This is a form of completion that may work for bash since it's completion system
is simpler and user expectation is (seemingly) solely "press tab and stuff appears".
where as zsh's completion systems allows the user to manipulating the results in
various ways which could be lost once $program handles the completion.

like adding additional results
overriding opinionated file completion set by the author(s)
omitting options you don't want presented to you.
grouping results by tags.
just to name a few.

zsh's completion system is far more powerful than just presenting a pseudo static
list of options with descriptions.



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

* Re: [RFC/PATCH] completion: git: add fast mode
  2020-11-25 22:56     ` Eric Cook
@ 2020-11-26  0:22       ` Felipe Contreras
  0 siblings, 0 replies; 7+ messages in thread
From: Felipe Contreras @ 2020-11-26  0:22 UTC (permalink / raw)
  To: Eric Cook; +Cc: Zsh hackers list

On Wed, Nov 25, 2020 at 4:56 PM Eric Cook <llua@gmx.com> wrote:
>
> On 11/25/20 5:34 PM, Felipe Contreras wrote:
> > I think the overall end goal would be to move as much as possible of
> > the completion to the Git project itself. For example; git commands
> > have the --git-completion-helper option, which throw something like:
> >
> >    % git version --git-completion-helper
> >    --build-options --no-build-options
> >
> > There is no _git_version() specific function in Git's bash completion,
> > and yet when you type "git version --<tab>" the options are completed
> > anyway.
> >
> > This helps so that new commands get some automatic completion, even
> > when nothing specific for them is done in the completion script.
> >
> > It has been discussed in the mailing list to add something similar for
> > zsh specific completion, so the descriptions are generated too, and
> > shorthand forms, perhaps with --git-completion-helper=zsh.
>
> This is a form of completion that may work for bash since it's completion system
> is simpler and user expectation is (seemingly) solely "press tab and stuff appears".
> where as zsh's completion systems allows the user to manipulating the results in
> various ways which could be lost once $program handles the completion.
>
> like adding additional results
> overriding opinionated file completion set by the author(s)
> omitting options you don't want presented to you.
> grouping results by tags.
> just to name a few.
>
> zsh's completion system is far more powerful than just presenting a pseudo static
> list of options with descriptions.

This is a false dichotomy.

You can do both things: 1. extract the options and descriptions from
the git program, and 2. use code to rearrange them, group them, and do
whatever else you want with them.

-- 
Felipe Contreras



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

end of thread, other threads:[~2020-11-26  0:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-23 17:56 [RFC/PATCH] completion: git: add fast mode Felipe Contreras
2020-11-25  0:19 ` Daniel Shahaf
2020-11-25  3:54   ` Felipe Contreras
2020-11-25 14:48 ` Eric Cook
2020-11-25 22:34   ` Felipe Contreras
2020-11-25 22:56     ` Eric Cook
2020-11-26  0:22       ` Felipe Contreras

zsh-workers

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/zsh-workers

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 zsh-workers zsh-workers/ http://inbox.vuxu.org/zsh-workers \
		zsh-workers@zsh.org
	public-inbox-index zsh-workers

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


code repositories for the project(s) associated with this inbox:

	https://git.vuxu.org/mirror/zsh/

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