Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Re: Shuld it be so? and Re: _tar



Andrej Borsenkow wrote:

> bor@itsrm2:~%> l /u/l/m<TAB>
> 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*<TAB>
>   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*<TAB>
> bor@itsrm2:~%> l /home/bor/s\*
> 
> but
> 
> bor@itsrm2:~%> l /h/b/s/*<TAB>
> 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<TAB> 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 `[^<sep>]', where `<sep>' 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 `*<sep>'.
 
-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@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author