about summary refs log tree commit diff
path: root/Completion/Base
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Base')
-rw-r--r--Completion/Base/Completer/_complete8
-rw-r--r--Completion/Base/Core/_dispatch98
-rw-r--r--Completion/Base/Core/_normal123
-rw-r--r--Completion/Base/Utility/_contexts23
-rw-r--r--Completion/Base/Utility/_set_command31
5 files changed, 143 insertions, 140 deletions
diff --git a/Completion/Base/Completer/_complete b/Completion/Base/Completer/_complete
index 16e0f5e9f..23670f7c0 100644
--- a/Completion/Base/Completer/_complete
+++ b/Completion/Base/Completer/_complete
@@ -95,7 +95,7 @@ fi
 
 comp="$_comps[-first-]"
 if [[ -n "$comp" ]]; then
-  service="${_services[-first-]:--first-}"
+  service="${_servicecomps[-first-]:--first-}"
   ccarray[3]=-first-
   eval "$comp" && ret=0
   if [[ "$_compskip" = all ]]; then
@@ -124,7 +124,7 @@ else
   ccarray[3]="$cname"
 
   comp="$_comps[$cname]"
-  service="${_services[$cname]:-$cname}"
+  service="${_servicecomps[$cname]:-$cname}"
 
   # If not, we use default completion, if any.
 
@@ -134,9 +134,9 @@ else
       return 1
     fi
     comp="$_comps[-default-]"
+    service="${_servicecomps[-default-]:--default-}"
   fi
-  [[ -n "$comp" ]] &&
-      service="${_services[-default-]:--default-}" && eval "$comp" && ret=0
+  [[ -n "$comp" ]] && eval "$comp" && ret=0
 fi
 
 _compskip=
diff --git a/Completion/Base/Core/_dispatch b/Completion/Base/Core/_dispatch
new file mode 100644
index 000000000..124aea112
--- /dev/null
+++ b/Completion/Base/Core/_dispatch
@@ -0,0 +1,98 @@
+#autoload
+
+local comp pat val name i ret=1 _compskip="$_compskip"
+local curcontext="$curcontext" service str comptype noskip def
+local __comps __patcomps __postpatcomps __services
+
+# If we get the option `-s', we don't reset `_compskip'.
+
+while [[ "$1" = -[sd] ]]; do
+  if [[ "$1" = -s ]]; then
+    noskip=yes
+  else
+    def=yes
+  fi
+  shift
+done
+
+[[ -z "$noskip" ]] && _compskip=
+
+comptype=$1
+
+__comps=_$1
+
+(( ${(P)+__comps} )) || return 1
+
+__patcomps=_pat$1
+__postpatcomps=_postpat$1
+__services=_service$1
+
+shift
+
+# See if there are any matching pattern completions.
+
+if [[ "$_compskip" != (all|*patterns*) ]]; then
+
+  for str in "$@"; do
+    [[ -n "$str" ]] || continue
+    service="${${(e):-\$${__services}[\$str]}:-$str}"
+    for i in "${(@e):-\$${__patcomps}[(K)\$str]}"; do
+      "$i" && ret=0
+      if [[ "$_compskip" = *patterns* ]]; then
+        break
+      elif [[ "$_compskip" = all ]]; then
+        _compskip=''
+        return ret
+      fi
+    done
+  done
+fi
+
+# Now look up the names in the normal completion array.
+
+ret=1
+for str in "$@"; do
+  [[ -n "$str" ]] || continue
+  name="$str"
+  comp="${(e):-\$${__comps}[\$str]}"
+  service="${${(e):-\$${__services}[\$str]}:-$str}"
+
+  [[ -z "$comp" ]] || break
+done
+
+# And generate the matches, probably using default completion.
+
+if [[ -n "$comp" ]]; then
+  _compskip=patterns
+  eval "$comp" && ret=0
+  [[ "$_compskip" = (all|*patterns*) ]] && return ret
+elif [[ "$_compskip" != *default* ]]; then
+  name=-default-
+  comp="${(e):-\$${__comps}[-default-]}"
+fi
+
+if [[ "$_compskip" != (all|*patterns*) ]]; then
+  for str; do
+    [[ -n "$str" ]] || continue
+    service="${${(e):-\$${__services}[\$str]}:-$str}"
+    for i in "${(@e):-\$${__postpatcomps}[(K)\$str]}"; do
+      _compskip=default
+      "$i" && ret=0
+      if [[ "$_compskip" = *patterns* ]]; then
+        break
+      elif [[ "$_compskip" = all ]]; then
+        _compskip=''
+        return ret
+      fi
+    done
+  done
+fi
+
+[[ "$name" = -default- && -n "$comp" &&
+   "$_compskip" != (all|*default*) ]] &&
+  service="${${(e):-\$${__services}[-default-]}:--default-}" &&
+   eval "$comp" && ret=0
+
+_compskip=''
+
+return ret
diff --git a/Completion/Base/Core/_normal b/Completion/Base/Core/_normal
index 9ddfab1cd..028687fd1 100644
--- a/Completion/Base/Core/_normal
+++ b/Completion/Base/Core/_normal
@@ -1,20 +1,16 @@
 #compdef -command-line-
 
-local comp command cmd1 cmd2 pat val name i ret=1 _compskip="$_compskip"
-local curcontext="$curcontext" service
+local _comp_command1 _comp_command2 skip
 
-# If we get the option `-s', we don't reset `_compskip'. This ensures
-# that a value set in the function for the `-first-' context is kept,
-# but that we still use pattern functions when we were called form
-# another completion function.
-
-[[ "$1" = -s ]] || _compskip=''
+if [[ "$1" = -s ]]; then
+  skip=(-s)
+else
+  skip=()
+  _compskip=''
+fi
 
-# Completing in command position? If not we set up `cmd1' and `cmd2' as
-# two strings we have to search in the completion definition arrays (e.g.
-# a path and the last path name component).
+# Completing in command position?
 
-command="$words[1]"
 if [[ CURRENT -eq 1 ]]; then
   curcontext="${curcontext%:*:*}:-command-:"
 
@@ -22,107 +18,8 @@ if [[ CURRENT -eq 1 ]]; then
   [[ -n "$comp" ]] && eval "$comp" && ret=0
 
   return ret
-else
-  if (( $+builtins[$command] + $+functions[$command] )); then
-    cmd1="$command"
-    curcontext="${curcontext%:*:*}:${cmd1}:"
-  elif [[ "$command[1]" = '=' ]]; then
-    eval cmd1\=$command
-    cmd2="$command[2,-1]"
-    curcontext="${curcontext%:*:*}:${cmd2}:"
-  elif [[ "$command" = ..#/* ]]; then
-    cmd1="${PWD}/$command"
-    cmd2="${command:t}"
-    curcontext="${curcontext%:*:*}:${cmd2}:"
-  elif [[ "$command" = */* ]]; then
-    cmd1="$command"
-    cmd2="${command:t}"
-    curcontext="${curcontext%:*:*}:${cmd2}:"
-  else
-    cmd1="$command"
-    cmd2="$commands[$command]"
-    curcontext="${curcontext%:*:*}:${cmd1}:"
-  fi
-fi
-
-# See if there are any matching pattern completions.
-
-if [[ "$_compskip" != (all|*patterns*) ]]; then
-  service="${_services[$cmd1]:-$cmd1}"
-  for i in "${(@)_patcomps[(K)$cmd1]}"; do
-    "$i" && ret=0
-    if [[ "$_compskip" = *patterns* ]]; then
-      break
-    elif [[ "$_compskip" = all ]]; then
-      _compskip=''
-      return ret
-    fi
-  done
-  if [[ -n "$cmd2" ]]; then
-    service="${_services[$cmd2]:-$cmd2}"
-    for i in "${(@)_patcomps[(K)$cmd2]}"; do
-      "$i" && ret=0
-      if [[ "$_compskip" = *patterns* ]]; then
-        break
-      elif [[ "$_compskip" = all ]]; then
-        _compskip=''
-        return ret
-      fi
-    done
-  fi
-fi
-
-# Now look up the two names in the normal completion array.
-
-ret=1
-name="$cmd1"
-comp="$_comps[$cmd1]"
-service="${_services[$cmd1]:-$cmd1}"
-
-[[ -z "$comp" ]] &&
-    name="$cmd2" comp="$_comps[$cmd2]" service="${_services[$cmd2]:-$cmd2}"
-
-# And generate the matches, probably using default completion.
-
-if [[ -n "$comp" ]]; then
-  _compskip=patterns
-  eval "$comp" && ret=0
-  [[ "$_compskip" = (all|*patterns*) ]] && return ret
-elif [[ "$_compskip" != *default* ]]; then
-  name=-default-
-  comp="$_comps[-default-]"
-fi
-
-if [[ "$_compskip" != (all|*patterns*) ]]; then
-  service="${_services[$cmd1]:-$cmd1}"
-  for i in "${(@)_postpatcomps[(K)$cmd1]}"; do
-    _compskip=default
-    "$i" && ret=0
-    if [[ "$_compskip" = *patterns* ]]; then
-      break
-    elif [[ "$_compskip" = all ]]; then
-      _compskip=''
-      return ret
-    fi
-  done
-  if [[ -n "$cmd2" ]]; then
-    service="${_services[$cmd2]:-$cmd2}"
-    for i in "${(@)_postpatcomps[(K)$cmd2]}"; do
-      _compskip=default
-      "$i" && ret=0
-      if [[ "$_compskip" = *patterns* ]]; then
-        break
-      elif [[ "$_compskip" = all ]]; then
-        _compskip=''
-        return ret
-      fi
-    done
-  fi
 fi
 
-[[ "$name" = -default- && -n "$comp" && "$_compskip" != (all|*default*) ]] &&
-  service="${_services[-default-]:--default-}" && eval "$comp" && ret=0
-
-_compskip=''
+_set_command
 
-return ret
+_dispatch -d "$skip[@]" comps "$_comp_command1" "$_comp_command2"
diff --git a/Completion/Base/Utility/_contexts b/Completion/Base/Utility/_contexts
deleted file mode 100644
index f0e5ba874..000000000
--- a/Completion/Base/Utility/_contexts
+++ /dev/null
@@ -1,23 +0,0 @@
-#autoload
-
-# This searches $* in the array for normal completions and calls the result.
-# It is used to include completions for another command or special context
-# into the list generated by the calling function.
-# For example the function for `-subscript-' could call this as in
-# `_contexts -math-' to get the completions that would be generated for a
-# mathematical context.
-
-local i tmp ret=1 service or
-
-if [[ $1 = -o ]]; then
-  or=yes
-  shift
-fi
-
-for i; do
-  tmp="$_comps[$i]"
-  [[ -n "$tmp" ]] && service="${_services[$i]:-$i}" && eval "$tmp" && ret=0
-  [[ -n "$or" && ret -eq 0 ]] && return 0
-done
-
-return ret
diff --git a/Completion/Base/Utility/_set_command b/Completion/Base/Utility/_set_command
new file mode 100644
index 000000000..daf532686
--- /dev/null
+++ b/Completion/Base/Utility/_set_command
@@ -0,0 +1,31 @@
+#autoload
+
+# This sets the parameters _comp_command1 and _comp_command2 in the
+# calling function.
+
+local command
+
+command="$words[1]"
+
+[[ -z "$command" ]] && return
+
+if (( $+builtins[$command] + $+functions[$command] )); then
+  _comp_command1="$command"
+  curcontext="${curcontext%:*:*}:${_comp_command1}:"
+elif [[ "$command[1]" = '=' ]]; then
+  eval _comp_command2\=$command
+  _comp_command1="$command[2,-1]"
+  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+elif [[ "$command" = ..#/* ]]; then
+  _comp_command1="${PWD}/$command"
+  _comp_command2="${command:t}"
+  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+elif [[ "$command" = */* ]]; then
+  _comp_command1="$command"
+  _comp_command2="${command:t}"
+  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+else
+  _comp_command1="$command"
+  _comp_command2="$commands[$command]"
+  curcontext="${curcontext%:*:*}:${_comp_command1}:"
+fi