From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17278 invoked from network); 5 Mar 1999 11:04:10 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 5 Mar 1999 11:04:10 -0000 Received: (qmail 10228 invoked by alias); 5 Mar 1999 11:03:34 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 5651 Received: (qmail 10221 invoked from network); 5 Mar 1999 11:03:32 -0000 Date: Fri, 5 Mar 1999 12:02:44 +0100 (MET) Message-Id: <199903051102.MAA03885@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: "Andrej Borsenkow"'s message of Thu, 4 Mar 1999 20:38:20 +0300 Subject: PATCH: Re: Shuld it be so? and Re: _tar Andrej Borsenkow wrote: > bor@itsrm2:~%> l /u/l/m > bor@itsrm2:~%> l /u1/lager-db/minileit.dbs/ > u1/ usr/ > ^^^^^^^^^^ Somewhat strange. We really have /usr/lib/macros (and more), but > this list is a bit unexpected (well, at least I would expect then to first > menu complete ``/u1'' and ``/usr'' and then go on respectively) It now keeps the original suffix if menucompletion is used. With normal completion it still tries to build as long a suffix as possible. [Again, I had forgotten menucompletion (I just can't imagine how one would like to use it... a matter of being used to, I think).] Anyway, if you try it, you will notice, that the cursor is left at the end of the whole string, even though only the beginning is cycled through. Since I don't like menucompletion I have to ask: would you like to have the cursor after the changed/listed component? (I'm not sure if I can manage to implement that, though.) This required a fix in tricky.c. But then I also found a memory bug there (with -P, -S). Peter: the memory problem you reported lately, was there a -S used somewhere? > And one more: > > bor@itsrm2:~%> l /u/l/lib*X* > B-e-e-p > > Is it not possible to complete glob patterns? This is now allowed if `globcomplete' is set. Otherwise the pattern characters will still be quoted (which is a good thing, I think). > bor@itsrm2:~%> l -d ~/s* > /home/bor/save/ /home/bor/src/ > > bor@itsrm2:~%> l /h/b/s* > bor@itsrm2:~%> l /home/bor/s\* > > but > > bor@itsrm2:~%> l /h/b/s/* > bor@itsrm2:~%> l /home/bor/save/* > save/ src/ > > the list is correct - it cycles through ``svae'' and ``src'' This should now give the same result in both cases (quoted `*'). Peter Stephenson wrote: > Sven Wischnowsky wrote: > > It was too eager to replace `*s' with `[^/]#'s. The patch below does > > the replacement only for the non-last components. > > Working a lot better now, thanks. It's maybe a little bit eager to stick > in later path components: if I type zsh-3.1.5-pws-10/Sr it completes > (with menucompletion) all the way to Src/.cvisignore instead of hanging > around at the next slash. I suppose normally with ordinary completion > it'll stop after the slash because the rest is ambiguous, but that won't > always be the case. Hm. For directory prefixes, yes. But without menucompletion the code should still try to insert as good a suffix as it can (and it *can* ;-). I hope the behavior it shows now suits you. > By the way, I think you can turn things like > > eval patstr\="\$patstr:gs-${sep}-\*${sep}-:gs/\*\*/\*/" > > into > > patstr="${${patstr//$sep/*$sep}//\*##/*}" Ouch. I had thought about using that, but then saw the slashes and... Although I knew that the strings are expanded after parsing the `${...//.../...}'. What a disgusting thinko. Thanks for the reminder. Oh, and I have made `_multi_parts' accept `-X', `-J', `-V' - just like `_comp_parts'. Bye Sven diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c --- os/Zle/zle_tricky.c Thu Mar 4 11:17:00 1999 +++ Src/Zle/zle_tricky.c Fri Mar 5 10:03:29 1999 @@ -4205,7 +4205,8 @@ t = s; if (ppre) t = dyncat(ppre, t); - if (!cp && !ms && mstack) { + lc = NULL; + if (!cp && !ms && (mstack || psuf)) { int bl = ((aflags & CAF_MATCH) ? llpl : 0); Cline *clp = &lc, tlc; char *ss = dupstring(s), *ee = me + (ss - s); @@ -4274,7 +4275,7 @@ lc = tlc; } else ai->iprefix = ""; - if (!ms && !mstack) { + if (!ms && !mstack && !lc) { if ((aflags & CAF_MATCH) || ai->cpl > pl) ai->cpl = pl; if ((aflags & CAF_MATCH) || ai->csl > lsl) @@ -7072,8 +7073,8 @@ r->ppre = ztrdup(m->ppre); r->psuf = ztrdup(m->psuf); r->prpre = ztrdup(m->prpre); - r->pre = m->pre; - r->suf = m->suf; + r->pre = ztrdup(m->pre); + r->suf = ztrdup(m->suf); r->flags = m->flags; r->brpl = m->brpl; r->brsl = m->brsl; @@ -7189,6 +7190,8 @@ zsfree(m->ripre); zsfree(m->ppre); zsfree(m->psuf); + zsfree(m->pre); + zsfree(m->suf); zsfree(m->prpre); zsfree(m->rems); zsfree(m->remf); diff -u oc/Core/_multi_parts Completion/Core/_multi_parts --- oc/Core/_multi_parts Fri Mar 5 10:13:31 1999 +++ Completion/Core/_multi_parts Fri Mar 5 12:00:55 1999 @@ -7,7 +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 gsep nm +local sep matches patstr orig matchflags pref i tmp1 tmp2 nm +local group expl _match_test _multi_parts || return 1 @@ -16,6 +17,18 @@ nm=$compstate[nmatches] +# Get the options. + +group=() +expl=() +while getopts "J:V:X:" opt; do + case "$opt" in + [JV]) group=("-$opt" "$OPTARG");; + X) expl=(-X "$OPTARG");; + esac +done +shift OPTIND-1 + # Get the arguments, first the separator, then the array. The array is # stored in `matches'. Further on this array will always contain those # words from the original array that still match everything we have @@ -28,33 +41,19 @@ matches=( "${(@P)2}" ) fi -# Since we will do some matching and this is not globbing, a `/' will -# not be treated specially in the matching. So we will have to replace -# `*'s we get by expressions of the form `[^]', where `' is -# our separator. We will do this using modifiers of the form -# `:gs/.../.../'. But if the separator is a slash, this will not work, -# so we need to get a character to separate the parts of the `:gs' -# that is different than the separator character we got. This -# character is stored in `gsep'. - -if [[ "$sep" = / ]]; then - gsep=. -else - gsep=/ -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 `*'. -patstr="${PREFIX:q}*${SUFFIX:q}*" -orig="${PREFIX:q}${SUFFIX:q}" +patstr="${PREFIX}*${SUFFIX}*" +orig="${PREFIX}${SUFFIX}" matchflags="" _match_pattern _path_files patstr matchflags [[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)" -eval patstr\="\$patstr:gs-${sep}-\*${sep}-:gs/\*\*/\*/" +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 @@ -67,8 +66,7 @@ # `matches' that match the prefix we have and the exact substring in # the array `tmp1'. - tmp1="${${patstr#*${sep}}%${sep}*}" - eval "pat=\"\${tmp1:gs${gsep}*${gsep}[^${sep}]#${gsep}}${patstr##*${sep}}\"" + pat="${${${patstr#*${sep}}%${sep}*}//\*/[^${sep}]#}${patstr##*${sep}}" tmp1=( "${(@M)matches:#${~matchflags}${orig%%${sep}*}${sep}${~pat}}" ) # If there are no words matching the exact substring, stop. @@ -89,7 +87,7 @@ if [[ "$patstr" = *${sep}* ]]; then tmp1="${patstr%${sep}*}${sep}" - eval "pat=\"\$tmp1:gs${gsep}*${gsep}[^${sep}]#${gsep}${patstr##*${sep}}\"" + pat="${tmp1//\*/[^${sep}]#}${patstr##*${sep}}" else pat="$patstr" fi @@ -116,19 +114,39 @@ pref="$pref$tmp1" matches=( "${(@)${(@)matches#$tmp1}:#}" ) - done - - # Now we can tell the completion code about the things we - # found. Strings that have a separator will be added with a suffix. - for i in "$matches[@]" ; do - if [[ "$i" = *${sep}* ]]; then - compadd -U -i "$IPREFIX" -p "$pref" -s "${sep}${i#*${sep}}" - "${i%%${sep}*}" + if [[ "$orig" = *${sep}* ]]; then + orig="${orig#*${sep}}" else - compadd -U -i "$IPREFIX" -p "$pref" - "$i" + orig='' fi done + # 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" -S '' - "${pref}${orig}" + elif [[ $compstate[insert] = *menu ]]; then + for i in "$matches[@]" ; do + if [[ "$i" = *${sep}* ]]; then + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \ + -p "$pref" -qS "$sep" - "${i%%${sep}*}" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \ + -p "$pref" - "${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}*}" + else + compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -p "$pref" - "$i" + fi + done + fi elif [[ "$patstr" = *${sep}* ]]; then # We had no words matching the string from the line. But we want to @@ -154,7 +172,7 @@ # the completion code together with our prefix and the rest of # the string from the line as the suffix. - compadd -U -S '' -i "$IPREFIX" -p "$pref" \ + compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -p "$pref" \ -s "${sep}${orig#*${sep}}" - "${(@)matches%%${sep}*}" return 0 fi @@ -171,7 +189,7 @@ # Finally, add the unambiguous prefix and the rest of the string # from the line. - compadd -U -S '' -i "$IPREFIX" -p "$pref" - "$orig" + compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -p "$pref" - "$orig" fi # This sets the return value to indicate that we added matches (or not). diff -u oc/Core/_path_files Completion/Core/_path_files --- oc/Core/_path_files Thu Mar 4 16:53:13 1999 +++ Completion/Core/_path_files Fri Mar 5 10:56:21 1999 @@ -91,7 +91,7 @@ # str holds the whole string from the command line with a `*' between # the prefix and the suffix. -str="${PREFIX:q}*${SUFFIX:q}" +str="${PREFIX}*${SUFFIX}" # If the string began with a `~', the quoting turned this into `\~', # remove the slash. @@ -251,10 +251,14 @@ done # If this test showed that none of the matches from the glob in `tmp1' - # has a possible sub-path matching what's on the line, we give up and - # continue with the next `-W' path. + # has a possible sub-path matching what's on the line, we add the + # matches found in `tmp1' and otherwise give up and continue with the + # next `-W' path. if [[ $#collect -eq 0 ]]; then + compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ + -i "$IPREFIX" -p "$linepath$testpath" -S "/${ostr#*/}" \ + -W "$tmp1" -f "$ignore[@]" - "$tmp1[@]" continue 2 elif [[ $#collect -ne 1 ]]; then # If we have more than one possible match, this means that the @@ -279,11 +283,17 @@ # these are file names and that `fignore' should be used as usual # (the `-f' and `-F' options). - for i in $collect; do + if [[ $compstate[insert] = *menu ]]; then compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ - -i "$IPREFIX" -p "$linepath$testpath" -s "/${i#*/}" \ - -W "$tmp1" -f "$ignore[@]" - "${i%%/*}" - done + -i "$IPREFIX" -p "$linepath$testpath" -S "/${ostr#*/}" \ + -W "$tmp1" -f "$ignore[@]" - "${(@)collect%%/*}" + else + for i in $collect; do + compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ + -i "$IPREFIX" -p "$linepath$testpath" -s "/${i#*/}" \ + -M 'r:|/=*' -W "$tmp1" -f "$ignore[@]" - "${i%%/*}" + done + fi # We have just finished handling all the matches from above, so we # can continue with the next `-W' path. @@ -324,7 +334,7 @@ # But only if something changed. [[ "$linepath$testpath$ostr" = "$PREFIX$SUFFIX" ]] && return - compadd -U -S '' "$group[@]" "$expl[@]" \ + compadd -QU -S '' "$group[@]" "$expl[@]" \ -i "$IPREFIX" -f - "$linepath$testpath$ostr" else compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ -- Sven Wischnowsky wischnow@informatik.hu-berlin.de