about summary refs log tree commit diff
path: root/Completion/Core/_multi_parts
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Core/_multi_parts')
-rw-r--r--Completion/Core/_multi_parts65
1 files changed, 45 insertions, 20 deletions
diff --git a/Completion/Core/_multi_parts b/Completion/Core/_multi_parts
index 1f51d2f6d..0c677aab7 100644
--- a/Completion/Core/_multi_parts
+++ b/Completion/Core/_multi_parts
@@ -8,7 +8,7 @@
 # separator character are then completed independently.
 
 local sep matches patstr orig matchflags pref i tmp1 tmp2 nm
-local group expl
+local group expl menu origflags mflags
 
 _match_test _multi_parts || return 1
 
@@ -42,22 +42,25 @@ else
 fi
 
 # Now build the pattern from what we have on the line. We also save
-# the original string in `orig'. The `eval' is used to replace our
-# separator character by `*<sep>'.
+# the original string in `orig'.
 
-if [[ -o globcomplete ]]; then
+if [[ $#compstate[pattern_match] -ne 0 ]]; then
   patstr="${PREFIX}*${SUFFIX}*"
 else
   patstr="${PREFIX:q}*${SUFFIX:q}*"
 fi
 orig="${PREFIX}${SUFFIX}"
 
+[[ $compstate[insert] = *menu || -n "$_comp_correct" ||
+   ( $#compstate[pattern_match] -ne 0 &&
+     "$orig" != "${orig:q}" ) ]] && menu=yes
+
 matchflags=""
 _match_pattern _path_files patstr matchflags
+origflags="$matchflags"
 [[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
 
 patstr="${${patstr//$sep/*$sep}//\*##/*}"
-#eval patstr\="\$patstr:gs-${sep}-\*${sep}-:gs/\*\*/\*/"
 
 # First we will skip over those parts of the matches for which we have 
 # exact substrings on the line. In `pref' we will build the
@@ -70,19 +73,26 @@ while [[ "$orig" = *${sep}* ]] do
   # `matches' that match the prefix we have and the exact substring in 
   # the array `tmp1'.
 
-  pat="${${${patstr#*${sep}}%${sep}*}//\*/[^${sep}]#}${patstr##*${sep}}"
-  tmp1=( "${(@M)matches:#${~matchflags}${orig%%${sep}*}${sep}${~pat}}" )
+  if [[ -n "$_comp_correct" && "${#orig%%${sep}*}" -le _comp_correct ]]; then
+    mflags="$origflags"
+  else
+    mflags="$matchflags"
+  fi
+
+  pat="${${${patstr#*${sep}}%${sep}*}//\*/[^${sep}]#}"
+  tmp1=( "${(@M)matches:#${~mflags}${orig%%${sep}*}${sep}${~pat}}" )
 
   # If there are no words matching the exact substring, stop.
 
   (( $#tmp1 )) || break
 
   # Otherwise add the part to the prefix, remove it from the matches
-  # (which will also remove all words not matching the string at all), 
-  # and set `patstr' and `orig' to the next component.
+  # (and also remove all words not matching the string at all), and
+  # set `patstr' and `orig' to the next component.
 
-  pref="$pref${orig%%${sep}*}${sep}"
-  matches=( "${(@)${(@)matches#${orig%%${sep}*}${sep}}:#}" )
+  tmp1="${orig%%${sep}*}${sep}"
+  pref="$pref$tmp1"
+  matches=("${(@)${(@)${(@M)matches:#${tmp1}*}#$tmp1}:#}")
   orig="${orig#*${sep}}"
   patstr="${patstr#*${sep}}"
 done
@@ -95,11 +105,16 @@ if [[ "$patstr" = *${sep}* ]]; then
 else
   pat="$patstr"
 fi
-tmp1=( "${(@M)matches:#${~matchflags}${~pat}}" )
+if [[ -n "$_comp_correct" && "${#orig%%${sep}*}" -le _comp_correct ]]; then
+  mflags="$origflags"
+else
+  mflags="$matchflags"
+fi
+tmp1=( "${(@M)matches:#${~mflags}${~pat}}" )
 
 if (( $#tmp1 )); then
 
-  # There are words that are matched, put them int `matches' and then
+  # There are words that are matched, put them into `matches' and then
   # move all unambiguous components from the beginning into `pref'.
 
   matches=( "$tmp1[@]" )
@@ -113,7 +128,7 @@ if (( $#tmp1 )); then
     tmp2=( "${(@)matches:#${tmp1}*}" )
     (( $#tmp2 )) && break
 
-    # All matches have the same prefix, but it into `pref' and remove
+    # All matches have the same prefix, put it into `pref' and remove
     # it from the matches.
 
     pref="$pref$tmp1"
@@ -131,21 +146,26 @@ if (( $#tmp1 )); then
 
   if [[ -z "$orig" && "$PREFIX$SUFFIX" != "$pref$orig" ]]; then
     compadd -QU  "$group[@]" "$expl[@]" -i "$IPREFIX" -S '' - "${pref}${orig}"
-  elif [[ $compstate[insert] = *menu ]]; then
+  elif [[ -n "$menu" ]]; then
+    if [[ "$orig" = *${sep}* ]]; then
+      orig="${sep}${orig#*${sep}}"
+    else
+      orig=''
+    fi
     for i in "$matches[@]" ; do
       if [[ "$i" = *${sep}* ]]; then
         compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \
-	        -p "$pref" -qS "$sep" - "${i%%${sep}*}"
+	        -p "$pref" -s "$orig" - "${i%%${sep}*}${sep}"
       else
         compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \
-	        -p "$pref" - "${i%%${sep}*}"
+	        -p "$pref" -s "$orig" - "${i%%${sep}*}"
       fi
     done
   else
     for i in "$matches[@]" ; do
       if [[ "$i" = *${sep}* ]]; then
-        compadd -U -i "$IPREFIX" -p "$pref" -s "${sep}${i#*${sep}}" \
-	        "$group[@]" "$expl[@]" -M "r:|${sep}=*" - "${i%%${sep}*}"
+        compadd -U -i "$IPREFIX" -p "$pref" -s "${i#*${sep}}" \
+	        "$group[@]" "$expl[@]" -M "r:|${sep:q}=*" - "${i%%${sep}*}${sep}"
       else
         compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -p "$pref" - "$i"
       fi
@@ -163,7 +183,12 @@ elif [[ "$patstr" = *${sep}* ]]; then
     # First we get all words matching at least this component in
     # `tmp1'. If there are none, we give up.
 
-    tmp1=( "${(@M)matches:#${~matchflags}${~patstr%%${sep}*}${sep}*}" )
+    if [[ -n "$_comp_correct" && "${#orig%%${sep}*}" -le _comp_correct ]]; then
+      mflags="$origflags"
+    else
+      mflags="$matchflags"
+    fi
+    tmp1=( "${(@M)matches:#${~mflags}${~patstr%%${sep}*}${sep}*}" )
     (( $#tmp1 )) || break
 
     # Then we check if there are words that have a different prefix.