Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] _git: Improve handling of aliases



---
This handles all of the following aliases:

# simple
lg = log --format=one --graph --color

# nested
lga = lg --all

# nested with preceding git options
push-upstream = -c push.default=upstream pushv
pushv = push -v

# simple shell
l = !git -P lg -5

# shell pipeline (completion of last command)
conf = !git config -l --local | sort

PS: Even though unrelated I kept first 2 hunks that strip hanging
whitespaces.

 Completion/Unix/Command/_git | 83 ++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 42 deletions(-)

diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 9eeff6a..cff6750 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -2346,7 +2346,7 @@ __git_config_value () {
 # Helper to _git-config().  May be called by other functions, too, provided
 # that The caller has set $line, $state, and $opt_args as _git-config() would
 # set them:
-# 
+#
 # - set $line[1] to the option name being completed (even if completing an
 #   option value).
 # - set $opt_args to git-config(1) options, as set by _arguments in
@@ -2916,7 +2916,7 @@ __git_config_option-or-value () {
     for key in $git_present_options ; do
       if (( ${+git_options[(r)(#i)${(b)key}:*]} )); then
         # $key is already in git_options
-        continue 
+        continue
       elif (( ${+sections_that_permit_arbitrary_subsection_names[(r)${(b)key%%.*}]} )); then
         if [[ $key == *.*.* ]]; then
           # If $key isn't an instance of a known foo.*.bar:baz $git_options entry...
@@ -8082,35 +8082,8 @@ __git_color_attributes () {
 
 # Now, for the main drive...
 _git() {
-  if (( CURRENT > 2 )); then
-    local -a aliases
-    local -A git_aliases
-    local a k v
-    local endopt='!(-)--end-of-options'
-    aliases=(${(0)"$(_call_program aliases git config -z --get-regexp '\^alias\.')"})
-    for a in ${aliases}; do
-        k="${${a/$'\n'*}/alias.}"
-        v="${a#*$'\n'}"
-        git_aliases[$k]="$v"
-    done
-
-    if (( $+git_aliases[$words[2]] && !$+commands[git-$words[2]] && !$+functions[_git-$words[2]] )); then
-      local -a tmpwords expalias
-      expalias=(${(z)git_aliases[$words[2]]})
-      tmpwords=(${words[1]} ${expalias})
-      if [[ -n "${words[3,-1]}" ]] ; then
-          tmpwords+=(${words[3,-1]})
-      fi
-      [[ -n ${words[$CURRENT]} ]] || tmpwords+=('')
-      (( CURRENT += ${#expalias} - 1 ))
-      words=("${tmpwords[@]}")
-      unset tmpwords expalias
-    fi
-
-    unset git_aliases aliases
-  fi
-
   integer ret=1
+  local -a allwords=("${words[@]}")
 
   if [[ $service == git ]]; then
     local curcontext=$curcontext state line
@@ -8143,18 +8116,44 @@ _git() {
         _git_commands && ret=0
         ;;
       (option-or-argument)
-        curcontext=${curcontext%:*:*}:git-$words[1]:
-        (( $+opt_args[--git-dir] )) && local -x GIT_DIR=${(Q)${~opt_args[--git-dir]}}
-        (( $+opt_args[--work-tree] )) && local -x GIT_WORK_TREE=${(Q)${~opt_args[--work-tree]}}
-	if ! _call_function ret _git-$words[1]; then
-	  if [[ $words[1] = \!* ]]; then
-	    words[1]=${words[1]##\!}
-	    _normal && ret=0
-	  elif zstyle -T :completion:$curcontext: use-fallback; then
-	    _default && ret=0
-	  else
-	    _message "unknown sub-command: $words[1]"
-	  fi
+        local -a aliases
+        local -A git_aliases
+        local a k v
+        local endopt='!(-)--end-of-options'
+        aliases=(${(0)"$(_call_program aliases git config -z --get-regexp '\^alias\.')"})
+        for a in $aliases; do
+          k=${${a/$'\n'*}/alias.}
+          v=${a#*$'\n'}
+          git_aliases[$k]=$v
+        done
+        local git_alias=git_aliases[\$words[1]]
+        if (( ${(P)+git_alias} && !$+commands[git-$words[1]] && !$+functions[_git-$words[1]] )); then
+          git_alias=${(P)git_alias}
+          local len=$#words
+          if [[ $git_alias = \!* ]]; then
+            local i
+            local -a git_alias_tail
+            for i in "${(z)git_alias##\!}"; do
+              git_alias_tail+=("$i")
+              [[ $i = \| ]] && git_alias_tail=()
+            done
+            words=("$git_alias_tail[@]" "${words[@]:1}")
+          else
+            words=("${allwords[@]:0:-$#words}" "${(z)git_alias}" "${words[@]:1}")
+          fi
+          (( CURRENT += $#words - len ))
+          _normal -P && ret=0
+        else
+          curcontext=${curcontext%:*:*}:git-$words[1]:
+          (( $+opt_args[--git-dir] )) && local -x GIT_DIR=${(Q)${~opt_args[--git-dir]}}
+          (( $+opt_args[--work-tree] )) && local -x GIT_WORK_TREE=${(Q)${~opt_args[--work-tree]}}
+          if ! _call_function ret _git-$words[1]; then
+            if zstyle -T :completion:$curcontext: use-fallback; then
+              _default && ret=0
+            else
+              _message "unknown sub-command: $words[1]"
+            fi
+          fi
         fi
         ;;
       (configuration)
-- 
2.27.0




Messages sorted by: Reverse Date, Date, Thread, Author