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

Re: PATCH 3/5: _imagemagick: complete all files if image files didn't match



Bart wrote:
> As I think I've mentioned elsewhere, file-patterns seems to take
> precedence over list-dirst-first anyway.  So I suppose it could be
> interpreted as a shorthand, except for the other-files business.

Yes, it is harmless enough as a shorthand.

> That bit is probably trying to do the trick of merging together glob
> qualifiers, and just gets it wrong.  I.e. here:
> 
>     # add `^-/' after `#q' glob qualifier if not there already
>     if [[ "$glob" = (#b)(*\(\#q)(*\)) ]]; then
>       [[ $match[2] != \^-/* ]] &&
>       glob="${match[1]}^-/,${match[2]}"
>     else
>       glob="$glob(#q^-/)"
>     fi

That bit is also getting it wrong: , in a list of glob qualifiers is an
OR and it wants an AND in this case. Just glob="$glob(#q^-/)" would
have done the job.
(The older attempt at merging qualifiers did want an OR which is harder
to do).

> Does it ever make sense to use  _files -g '*(/)' ?  Or should -/ always
> be used in that case?

In that exact example, -/ should be used but there's definitely
use-cases for globs matching only some directories. For example, to
select a git repository you might want *(e:[[ -d \$REPLY/.git ]]:)

We don't tend to bother in the functions because the directories get
picked up for the directories tag anyway and there's no way to tell the
selected directories apart from those only there because they might be
part of the path to the final directory. You can't use complist colours
because that works on the basis of the group rather than the tag. If you
use separate groups then you get matches duplicated.

Instead of *(-/) for the directories, we ideally need to negate the glob
specified with -g. The trouble is that it is actually quite hard to get
the opposite of a glob. The opposite of *.ext(ab,cd) is something like
^*.ext *.ext(^a,^b)(^c,^d)
It'd probably be easier to expand the glob in an array and use that
array as a filter. I'd be interested if anyone has any ideas on how to
do this.

The patch below strips the defaults down to a single pattern regardless
of -/ and -g. This makes things more consistent with the use of
a file-patterns style.

Oliver

diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files
index a8ba9b3..fe0780a 100644
--- a/Completion/Unix/Type/_files
+++ b/Completion/Unix/Type/_files
@@ -33,6 +33,8 @@ if (( $tmp[(I)-g*] )); then
   # add `#q' to the beginning of any glob qualifier if not there already
   [[ "$glob" = (#b)(*\()([^\|\~]##\)) && $match[2] != \#q* ]] &&
       glob="${match[1]}#q${match[2]}"
+elif [[ $type = */* ]]; then
+  glob="*(-/)"
 fi
 tmp=$opts[(I)-F]
 if (( tmp )); then
@@ -51,59 +53,21 @@ else
 fi
 
 if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
-  [[ "$type" = */* ]] && glob="$glob,*(-/)"
   pats=()
 
   for i in ${tmp//\%p/${${glob:-\*}//:/\\:}}; do
     if [[ $i = *[^\\]:* ]]; then
-      pats=( "$pats[@]" " $i " )
+      pats+=( " $i " )
     else
-      pats=( "$pats[@]" " ${i}:files " )
+      pats+=( " ${i}:files " )
     fi
   done
 elif zstyle -t ":completion:${curcontext}:" list-dirs-first; then
-  if [[ "$type" = *g* ]]; then
-
-    # add `^-/' after `#q' glob qualifier if not there already
-    if [[ "$glob" = (#b)(*\(\#q)(*\)) ]]; then
-      [[ $match[2] != \^-/* ]] &&
-      glob="${match[1]}^-/,${match[2]}"
-    else
-      glob="$glob(#q^-/)"
-    fi
-
-    pats=( " *(-/):directories:directories ${glob//:/\\:}:globbed-files" )
-  elif [[ "$type" = */* ]] then
-    pats=( '*(-/):directories ' '*:all-files ' )
-  else
-    pats=( '*(-/):directories:directories *(^-/):other-files ' )
-  fi
+  pats=( " *(-/):directories:directory ${${glob:-*}//:/\\:}(#q^-/):globbed-files" '*:all-files' )
 else
-  if [[ "$type" = *g* ]]; then
-
   # People prefer to have directories shown on first try as default.
   # Even if the calling function didn't use -/.
-  #
-  # if [[ "$type" = */* ]]; then
-
-    pats=( " ${glob//:/\\:}:globbed-files *(-/):directories" '*:all-files '
-
-    ### We could allow _next_tags to offer only globbed-files or directories
-    ### by adding:
-    ###   " ${glob//:/\\:}:only-globbed-files " ' *(-/):only-directories '
-
-      )
-
-  # else
-  #   pats=( " ${glob//:/\\:}:globbed-files "
-  #          '*(-/):directories ' '*:all-files ' )
-  # fi
-
-  elif [[ "$type" = */* ]]; then
-    pats=( '*(-/):directories ' '*:all-files ' )
-  else
-    pats=( '*:all-files ' )
-  fi
+  pats=( "${${glob:-*}//:/\\:}:globbed-files *(-/):directories" '*:all-files ' )
 fi
 
 tried=()



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