From 8ceb54fbc2f879e0e80f58c18761bd54db07e5f7 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 15 Apr 1999 18:25:40 +0000 Subject: zsh-3.1.5-pws-15 --- Completion/Core/_multi_parts | 287 +++++++++++++++++++------------------------ 1 file changed, 123 insertions(+), 164 deletions(-) (limited to 'Completion/Core/_multi_parts') diff --git a/Completion/Core/_multi_parts b/Completion/Core/_multi_parts index ab9438494..b49c41e22 100644 --- a/Completion/Core/_multi_parts +++ b/Completion/Core/_multi_parts @@ -7,15 +7,8 @@ # The parts of words from the array that are separated by the # separator character are then completed independently. -local sep matches patstr orig matchflags pref i tmp1 tmp2 nm -local group expl menu origflags mflags - -_match_test _multi_parts || return 1 - -# Save the current number of matches to be able to return if we added -# matches or not. - -nm=$compstate[nmatches] +local sep matches pref npref i tmp1 group expl menu pre suf +typeset -U tmp2 # Get the options. @@ -41,193 +34,159 @@ else matches=( "${(@P)2}" ) fi -# Now build the pattern from what we have on the line. We also save -# the original string in `orig'. +# In `pre' and `suf' we will hold the prefix and the suffix from the +# line while we walk through them. The original string are used +# temporarily for matching. -if [[ $#compstate[pattern_match] -ne 0 ]]; then - if [[ "${compstate[pattern_match]-*}" = \** ]]; then - str="${PREFIX}*${SUFFIX}*" - else - str="${PREFIX}${SUFFIX}" - fi -else - patstr="${PREFIX:q}*${SUFFIX:q}*" -fi -orig="${PREFIX}${SUFFIX}" +pre="$PREFIX" +suf="$SUFFIX" +orig="$PREFIX$SUFFIX" -[[ $compstate[insert] = *menu || -n "$_comp_correct" || +# Special handling for menucompletion? + +[[ $compstate[insert] = (*menu|[0-9]*) || -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}//\*##/*}" - -# 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 -# unambiguous prefix string. +# In `pref' we collect the unambiguous prefix path. pref='' -while [[ "$orig" = *${sep}* ]] do - # First build the pattern to use, then collect all strings from - # `matches' that match the prefix we have and the exact substring in - # the array `tmp1'. +# If the string from the line matches at least one of the strings, +# we use only the matching strings. - 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}}" ) +compadd -O tmp1 -M "r:|${sep}=* r:|=*" - "$matches[@]" - # If there are no words matching the exact substring, stop. +(( $#tmp1 )) && matches=( "$tmp1[@]" ) - (( $#tmp1 )) || break +while true; do - # Otherwise add the part to the prefix, remove it from the matches - # (and also remove all words not matching the string at all), and - # set `patstr' and `orig' to the next component. + # Get the prefix and suffix for matching. - tmp1="${orig%%${sep}*}${sep}" - pref="$pref$tmp1" - matches=("${(@)${(@)${(@M)matches:#${tmp1}*}#$tmp1}:#}") - orig="${orig#*${sep}}" - patstr="${patstr#*${sep}}" -done - -# Now we get all the words that still match in `tmp1'. - -if [[ "$patstr" = *${sep}* ]]; then - tmp1="${patstr%${sep}*}${sep}" - pat="${tmp1//\*/[^${sep}]#}${patstr##*${sep}}" -else - pat="$patstr" -fi -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 into `matches' and then - # move all unambiguous components from the beginning into `pref'. + if [[ "$pre" = *${sep}* ]]; then + PREFIX="${pre%%${sep}*}" + SUFFIX="" + else + PREFIX="${pre}" + SUFFIX="${suf%%${sep}*}" + fi - matches=( "$tmp1[@]" ) - while [[ "$matches[1]" = *${sep}* ]]; do + # Check if the component for some of the possible matches is equal + # to the string from the line. If there are such strings, we directly + # use the stuff from the line. This avoids having `foo' complete to + # both `foo' and `foobar'. - # We just take the first component of the first match and see if - # there are other matches with a different prefix (these are - # collected in `tmp2'). If there are any, we give up. + tmp1=( "${(@M)matches:#${PREFIX}${SUFFIX}${sep}*}" ) - tmp1="${matches[1]%%${sep}*}${sep}" - tmp2=( "${(@)matches:#${tmp1}*}" ) - (( $#tmp2 )) && break + if (( $#tmp1 )); then + npref="${PREFIX}${SUFFIX}${sep}" + else + # No exact match, see how many strings match what's on the line. - # All matches have the same prefix, put it into `pref' and remove - # it from the matches. + tmp2=( "${(@)matches%%${sep}*}" ) + compadd -O tmp1 - "$tmp2[@]" - pref="$pref$tmp1" - matches=( "${(@)${(@)matches#$tmp1}:#}" ) + if [[ $#tmp1 -eq 1 ]]; then - if [[ "$orig" = *${sep}* ]]; then - orig="${orig#*${sep}}" - else - orig='' - fi - done + # Only one match. If there are still separators from the line + # we just accept this component. Otherwise we insert what we + # have collected, probably giving it a separator character + # as a suffix. - # Now we can tell the completion code about the things we - # found. Strings that have a separator will be added with a suffix. - - if [[ -z "$orig" && "$PREFIX$SUFFIX" != "$pref$orig" ]]; then - compadd -QU "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" -S '' - \ - "${pref}${orig}" - 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" -I "$ISUFFIX" \ - -p "$pref" -s "$orig" - "${i%%${sep}*}${sep}" + if [[ "$pre$suf" = *${sep}* ]]; then + npref="${tmp1[1]}${sep}" else - compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ - -p "$pref" -s "$orig" - "${i%%${sep}*}" + matches=( "${(@M)matches:#${tmp1[1]}*}" ) + tmp2=( "${(@M)matches:#${tmp1[1]}${sep}*}" ) + + if (( $#tmp2 )); then + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -p "$pref" -qS "$sep" - "$tmp1[1]" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -p "$pref" - "$tmp1[1]" + fi + return 1 fi - done - else - for i in "$matches[@]" ; do - if [[ "$i" = *${sep}* ]]; then - compadd -U -i "$IPREFIX" -I "$ISUFFIX" -p "$pref" -s "${i#*${sep}}" \ - "$group[@]" "$expl[@]" -M "r:|${sep:q}=*" - "${i%%${sep}*}${sep}" + elif (( $#tmp1 )); then + + # More than one match. First we get all strings that match the + # rest from the line. + + PREFIX="$pre" + SUFFIX="$suf" + compadd -O matches -M "r:|${sep}=* r:|=*" - "$matches[@]" + + 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. + + tmp2="$pre$suf" + if [[ "$tmp2" = *${sep}* ]]; then + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -p "$pref" -s "${sep}${tmp2#*${sep}}" - "$tmp1[@]" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -p "$pref" - "$tmp1[@]" + fi else - compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ - -p "$pref" - "$i" + # With normal completion we add all matches one-by-one with + # the unmatched part as a suffix. This will insert the longest + # unambiguous string for all matching strings. + + for i in "${(@M)matches:#(${(j:|:)~tmp1})*}"; do + if [[ "$i" = *${sep}* ]]; then + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -S '' -p "$pref" -s "${i#*${sep}}" - "${i%%${sep}*}${sep}" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -S '' -p "$pref" - "$i" + fi + done fi - done - fi -elif [[ "$patstr" = *${sep}* ]]; then - - # We had no words matching the string from the line. But we want to - # be friendly and at least expand the prefix as far as we can. So we - # will loop through the rest of the string from the line and test - # the components one by one. - - while [[ "$patstr" = *${sep}* ]]; do - - # First we get all words matching at least this component in - # `tmp1'. If there are none, we give up. - - if [[ -n "$_comp_correct" && "${#orig%%${sep}*}" -le _comp_correct ]]; then - mflags="$origflags" + return 0 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. + # We are here if no string matched what's on the line. In this + # case we insert the expanded prefix we collected if it differs + # from the original string from the line. - tmp2=( "${(@)tmp1:#${tmp1[1]%%${sep}*}${sep}*}" ) - if (( $#tmp2 )); then + [[ "$orig" = "$pref$pre$suf" ]] && return 1 - # There are words with another prefix, so we have found an - # ambiguous component. So we just give all possible prefixes to - # the completion code together with our prefix and the rest of - # the string from the line as the suffix. - - compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -I "$ISUFFIX" \ - -p "$pref" -s "${sep}${orig#*${sep}}" - "${(@)matches%%${sep}*}" + if [[ -n "$suf" ]]; then + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -s "$suf" - "$pref$pre" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -S '' - "$pref$pre$suf" + fi return 0 fi + fi - # All words have the same prefix, so add it to `pref' again and - # try the next component. + # We just accepted and/or expanded a component from the line. We + # remove it from the matches (using only those that have a least + # the skipped string) and ad it the `pref'. - pref="$pref${tmp1[1]%%${sep}*}${sep}" - matches=( "${(@)matches#${tmp1[1]%%${sep}*}${sep}}" ) - orig="${orig#*${sep}}" - patstr="${patstr#*${sep}}" - done + matches=( "${(@)${(@)${(@M)matches:#${npref}*}#*${sep}}:#}" ) + pref="$pref$npref" - # Finally, add the unambiguous prefix and the rest of the string - # from the line. + # Now we set `pre' and `suf' to their new values. - compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -I "$ISUFFIX" \ - -p "$pref" - "$orig" -fi + if [[ "$pre" = *${sep}* ]]; then + pre="${pre#*${sep}}" + elif [[ "$suf" = *${sep}* ]]; then + pre="${suf#*${sep}}" + suf="" + else + # The string from the line is fully handled. If we collected an + # unambiguous prefix and that differs from the original string, + # we insert it. -# This sets the return value to indicate that we added matches (or not). + [[ -n "$pref" && "$orig" != "$pref" ]] && + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \ + -S '' - "$pref" -[[ nm -ne compstate[nmatches] ]] + return + fi +done -- cgit 1.4.1