zsh-workers
 help / color / mirror / code / Atom feed
From: Felipe Contreras <felipe.contreras@gmail.com>
To: zsh-workers@zsh.org
Cc: Daniel Shahaf <d.s@daniel.shahaf.name>,
	Felipe Contreras <felipe.contreras@gmail.com>
Subject: [RFC/PATCH] completion: git: add fast mode
Date: Mon, 23 Nov 2020 11:56:41 -0600	[thread overview]
Message-ID: <20201123175641.2111934-1-felipe.contreras@gmail.com> (raw)

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



             reply	other threads:[~2020-11-23 17:57 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-23 17:56 Felipe Contreras [this message]
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

Reply instructions:

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

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

  git send-email \
    --in-reply-to=20201123175641.2111934-1-felipe.contreras@gmail.com \
    --to=felipe.contreras@gmail.com \
    --cc=d.s@daniel.shahaf.name \
    --cc=zsh-workers@zsh.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).