about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Completion/Core/_multi_parts65
-rw-r--r--Completion/Core/_path_files2
-rw-r--r--Doc/Zsh/compsys.yo7
3 files changed, 55 insertions, 19 deletions
diff --git a/Completion/Core/_multi_parts b/Completion/Core/_multi_parts
index 56c0a9985..4a9b4192c 100644
--- a/Completion/Core/_multi_parts
+++ b/Completion/Core/_multi_parts
@@ -8,14 +8,14 @@
 # separator character are then completed independently.
 
 local sep matches pref npref i tmp1 group expl menu pre suf opre osuf cpre
-local opts sopts match
+local opts sopts match imm
 typeset -U tmp2
 
 # Get the options.
 
 zparseopts -D -a sopts \
     'J:=group' 'V:=group' 'X:=expl' 'P:=opts' 'F:=opts' \
-    S: r: R: q 1 2 n 'M+:=match'
+    S: r: R: q 1 2 n 'M+:=match' 'i=imm'
 
 sopts=( "$sopts[@]" "$opts[@]" )
 if (( $#match )); then
@@ -93,7 +93,6 @@ while true; do
       compadd -O tmp1 - "${(@)matches%%${sep}*}"
 
     tmp2=( "$tmp1[@]" )
-    tmp1=( "$tmp2[@]" )
 
     if [[ $#tmp1 -eq 1 ]]; then
 
@@ -106,17 +105,23 @@ while true; do
         npref="${tmp1[1]}${sep}"
       else
         matches=( "${(@M)matches:#${tmp1[1]}*}" )
-	tmp2=( "${(@M)matches:#${tmp1[1]}${sep}*}" )
 
 	PREFIX="${cpre}${pre}"
 	SUFFIX="$suf"
 
-	if (( $#tmp2 )); then
-	  compadd "$group[@]" "$expl[@]" -p "$pref" -qS "$sep" "$opts[@]" \
-                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[1]"
+	if [[ $#imm -ne 0 && $#matches -eq 1 ]]; then
+	  compadd "$group[@]" "$expl[@]" "$opts[@]" \
+                  -M "r:|${sep}=* r:|=* $match" - "$pref$matches[1]"
         else
-	  compadd "$group[@]" "$expl[@]" -p "$pref" "$sopts[@]" \
-                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[1]"
+	  tmp2=( "${(@M)matches:#${tmp1[1]}${sep}*}" )
+
+	  if (( $#tmp2 )); then
+	    compadd "$group[@]" "$expl[@]" -p "$pref" -qS "$sep" "$opts[@]" \
+                    -M "r:|${sep}=* r:|=* $match" - "$tmp1[1]"
+          else
+	    compadd "$group[@]" "$expl[@]" -p "$pref" "$sopts[@]" \
+                    -M "r:|${sep}=* r:|=* $match" - "$tmp1[1]"
+          fi
         fi
 	return 0
       fi
@@ -137,20 +142,44 @@ while true; do
 	SUFFIX="$suf"
       fi
 
-      if [[ -n "$menu" ]]; then
-        # With menucompletion we just add matches for the matching
-        # components with the prefix we collected and the rest from the
-        # line as a suffix.
+      if [[ -n "$menu" || -z "$compstate[insert]" ]]; then
+
+        # With menucompletion we add only the ambiguous component with
+        # the prefix collected and a spearator for the matches that
+        # have more components.
 
         tmp2="$pre$suf"
         if [[ "$tmp2" = *${sep}* ]]; then
-          compadd "$group[@]" "$expl[@]" "$sopts[@]" \
-                  -p "$pref" -s "${sep}${tmp2#*${sep}}" \
-                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[@]"
+          tmp2=(-s "${sep}${tmp2#*${sep}}")
         else
-          compadd "$group[@]" "$expl[@]" -p "$pref" "$sopts[@]" \
-                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[@]"
+	  tmp2=()
         fi
+        for i in "${(@M)matches:#(${(j:|:)~tmp1})*}"; do
+	  if [[ "$i" = *${sep}* ]]; then
+            compadd "$group[@]" "$expl[@]" -S '' "$opts[@]" \
+	            -p "$pref" \
+                    -M "r:|${sep}=* r:|=* $match" - "${i%%${sep}*}${sep}"
+          else
+            compadd "$group[@]" "$expl[@]" -S '' "$opts[@]" -p "$pref" \
+                    -M "r:|${sep}=* r:|=* $match" - "$i"
+          fi
+        done
+
+# The old code and its comment:
+
+        # With menucompletion we just add matches for the matching
+        # components with the prefix we collected and the rest from the
+        # line as a suffix.
+
+#        tmp2="$pre$suf"
+#        if [[ "$tmp2" = *${sep}* ]]; then
+#          compadd "$group[@]" "$expl[@]" "$sopts[@]" \
+#                  -p "$pref" -s "${sep}${tmp2#*${sep}}" \
+#                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[@]"
+#        else
+#          compadd "$group[@]" "$expl[@]" -p "$pref" "$sopts[@]" \
+#                  -M "r:|${sep}=* r:|=* $match" - "$tmp1[@]"
+#        fi
       else
         # With normal completion we add all matches one-by-one with
 	# the unmatched part as a suffix. This will insert the longest
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index 62c52e3c4..7acab453c 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -439,7 +439,7 @@ for prepath in "$prepaths[@]"; do
       tmp2="$testpath"
       compquote tmp1 tmp2
 
-      if [[ -n $menu ]] ||
+      if [[ -n $menu || -z "$compstate[insert]" ]] ||
          ! zstyle -t ":completion:${curcontext}:paths" expand suffix; then
         (( tmp4 )) && zstyle -t ":completion:${curcontext}:paths" cursor &&
             compstate[to_end]=''
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index bbef94900..c3ae77ec0 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -2082,6 +2082,13 @@ tar file in an array and then calls this function to complete these
 names in the way normal filenames are completed by the
 tt(_path_files) function.
 
+If given the tt(-i) option a single match left will be accepted
+immediatly even if that means that additional parts for which no
+separators were on the line are to be inserted. When completing from a 
+fixed set of possible completions which are really words, this is
+often the expected behaviour. But if tt(_multi_parts) should behave
+like completing pathnames, the tt(-i) option should not be used.
+
 Like other utility functions, this function accepts the `tt(-V)',
 `tt(-J)', `tt(-1)', `tt(-2)', `tt(-n)', `tt(-X)', `tt(-M)', `tt(-P)',
 `tt(-S)', `tt(-r)', `tt(-R)', and `tt(-q)' options and passes them to