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

Re: PATCH: _path_files -/



Peter Stephenson wrote:

> Here's a small patch which stops _path_files -/ from returning matches for
> non-directories when the path before the last component gets expanded.
> Maybe Sven has a better way of doing this.  One thing I'm not sure about is
> that (e.g.) ./F/C/<TAB> doesn't give ./Functions/Completion/ because it
> wants another directory after the final /.  The question is whether we
> should get any directory under that one, when there is one, or whether in
> the first instance we should get ./Functions/Completion/, which is what you
> would get if that last slash wasn't there, and only next start completing
> in the directory.

I received this mail half an hour ago and was just working on
`_path_files' (was this a local problem or one with sunsite.auc.dk?).

Anyway, the patch below (which I have made so that it goes on top of
Peter's) improves the option handling in `defcomp' and in
`_path_files'. For the first one, options can be combined and the
order isn't important anymore. For `_path_files' you can now give the
options `-f', `-/', `-g str', `-J str', `-V str', `-W str', `-P str',
`-S str', and `-F str'. No more separated pattern arguments (stuff
them into `-g str'). Also the string for `-F' may now be an array name 
or a literal list (`(...)', as usual).

Peter's mail made my look into the `-/' problem and the patch below
should give the result one would want (only directories, but the path
on the line is always expanded).

Bye
 Sven

diff -u of/Completion/_comp_parts Functions/Completion/_comp_parts
--- of/Completion/_comp_parts	Wed Feb 24 15:11:38 1999
+++ Functions/Completion/_comp_parts	Thu Feb 25 11:09:10 1999
@@ -13,9 +13,8 @@
 # `friends'. If the string on the line contains a `@', the substring
 # after it will be completed from the array `hosts'. Of course more
 # arrays may be given, each preceded by another separator string.
-# This function does part of the matching itself, doing it as if a
-# matching specification like `-M "m :{a-z}={A-Z} r:|[.,-_]=* r:|=*"'
-# were used, so you might want to modify this function.
+# This function does part of the matching itself and calls the functions
+# `_match_test' and `_match_pattern' for this.
 
 local str arr sep test testarr tmparr prefix suffixes matchers autosuffix
 local matchflags
diff -u of/Completion/_dirs Functions/Completion/_dirs
--- of/Completion/_dirs	Wed Feb 24 15:11:38 1999
+++ Functions/Completion/_dirs	Thu Feb 25 10:35:25 1999
@@ -1,3 +1,3 @@
 #defcomp rmdir df du dircmp
 
-_files -/ '*(-/)'
+_files -/
diff -u of/Completion/_hash Functions/Completion/_hash
--- of/Completion/_hash	Wed Feb 24 15:11:39 1999
+++ Functions/Completion/_hash	Thu Feb 25 10:39:13 1999
@@ -7,7 +7,7 @@
     complist -n -q -S '='
   fi
 elif [[ -string 1 '=' ]]; then
-  _files -g '*(*)' '*(-/)'
+  _files -/g '*(*)'
 else
   complist -m -q -S '='
 fi
diff -u of/Completion/_path_files Functions/Completion/_path_files
--- of/Completion/_path_files	Thu Feb 25 11:07:53 1999
+++ Functions/Completion/_path_files	Thu Feb 25 11:06:48 1999
@@ -1,57 +1,87 @@
 #autoload
 
 # Utility function for in-path completion.
-# First argument should be an complist-option (e.g. -f, -/, -g). The other
-# arguments should be glob patterns, one per argument.
-#
-# E.g.: _path_files -g '*.tex' '*.texi'
-#
-# This is intended as a replacement for `complist -f', `complist -/', and
-# `complist -g ...' (but don't use it with other options).
-#
-# You may also give the `-W <spec>' option as with `compctl' and `complist',
-# but only as the first argument.
-#
-# This function also accepts an optional `-F <string>' option as its first
-# argument or just after the `-W <spec>'. This can be used to define file
-# name extension (a la `fignore'). Files with such an extension will not
-# be considered possible completions.
+# Supported arguments are: `-f', `-/', `-g <patterns>', `-J <group>',
+# `-V <group>', `-W paths', and `-F <ignore>'. All but the last have the
+# same syntax and meaning as for `complist'. The `-F <ignore>' option
+# may be used to give a list of suffixes either by giving the name of an
+# array or literally by giving them in a string surrounded by parentheses.
+# Files with one of the suffixes thus given are treated like files with
+# one of the suffixes in the `fignore' array in normal completion.
 #
 # This function uses the helper functions `_match_test' and `_match_pattern'.
 
-# First see if we should do generate matches for the global matcher in use.
+# First see if we should generate matches for the global matcher in use.
 
 _match_test _path_files || return
 
 # Yes, so...
 
 local nm prepaths str linepath realpath donepath patstr prepath testpath rest
-local tmp1 collect tmp2 suffixes i ignore matchflags comp_dirs
+local tmp1 collect tmp2 suffixes i ignore matchflags opt group sopt pats gopt
+local addpfx addsfx
 
 setopt localoptions nullglob rcexpandparam globdots extendedglob
 unsetopt markdirs globsubst shwordsplit nounset
 
-# Get the optional `-W' option and its argument.
-if [[ "$1" = -W ]]; then
-  tmp1="$2"
-  if [[ "$tmp1[1]" = '(' ]]; then
-    prepaths=( $tmp1[2,-2]/ )
+prepaths=('')
+ignore=()
+group=()
+sopt='-'
+gopt=''
+pats=()
+addpfx=()
+addsfx=()
+
+# Get the options.
+
+while getopts "P:S:W:F:J:V:f/g:" opt; do
+  case "$opt" in
+  P)     addpfx=(-P "$OPTARG")
+         ;;
+  S)     addsfx=(-S "$OPTARG")
+         ;;
+  W)     tmp1="$OPTARG"
+         if [[ "$tmp1[1]" = '(' ]]; then
+           prepaths=( ${^=tmp1[2,-2]}/ )
+         else
+           prepaths=( ${(P)=${tmp1}} )
+           (( ! $#prepaths )) && prepaths=( ${tmp1}/ )
+         fi
+         (( ! $#prepaths )) && prepaths=( '' )
+         ;;
+  F)     tmp1="$OPTARG"
+         if [[ "$tmp1[1]" = '(' ]]; then
+           ignore=( ${^=tmp1[2,-2]}/ )
+         else
+           ignore=( ${(P)${tmp1}} )
+         fi
+	 (( $#ignore )) && ignore=(-F "$ignore[@]")
+         ;;
+  [JV])  group=("-$opt" "$OPTARG")
+         ;;
+  f)     sopt="${sopt}f"
+         pats=("$pats[@]" '*')
+	 ;;
+  /)     sopt="${sopt}/"
+         pats=("$pats[@]" '*(-/)')
+	 ;;
+  g)     gopt='-g'
+         pats=("$pats[@]" ${=OPTARG})
+	 ;;
+  esac
+done
+
+# If we were given no file selection option, we behave as if we were given
+# a `-f'.
+
+if [[ "$sopt" = - ]]; then
+  if [[ -z "$gopt" ]]; then
+    sopt='-f'
+    pats=('*')
   else
-    prepaths=( ${(P)${tmp1}} )
-    [[ $#prepaths -eq 0 ]] && prepaths=( $tmp1/ )
+    unset sopt
   fi
-  [[ $#prepaths -eq 0 ]] && prepaths=( '' )
-  shift 2
-else
-  prepaths=( '' )
-fi
-
-# Get the optional `-F' option and its argument.
-if [[ "$1" = -F ]]; then
-  ignore=(-F "$2")
-  shift 2
-else
-  ignore=''
 fi
 
 # str holds the whole string from the command line with a `*' between
@@ -67,7 +97,7 @@
 # We will first try normal completion called with `complist', but only if we
 # weren't given a `-F' option.
 
-if [[ -z "$ignore" ]]; then
+if (( ! $#ignore )); then
   # First build an array containing the `-W' option, if there is any and we
   # want to use it. We don't want to use it if the string from the command line
   # is a absolute path or relative to the current directory.
@@ -81,15 +111,10 @@
   # Now call complist.
 
   nm=$NMATCHES
-  if [[ $# -eq 0 ]]; then
-    complist "$tmp1[@]" -f
-  elif [[ "$1" = -g ]]; then
-    complist "$tmp1[@]" -g "$argv[2,-1]"
-    shift
+  if [[ -z "$gopt" ]]; then
+    complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$tmp1[@]" $sopt
   else
-    [[ $1 = -/ ]] && comp_dirs=1
-    complist "$tmp1[@]" $1
-    shift
+    complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$tmp1[@]" $sopt -g "$pats"
   fi
 
   # If this generated any matches, we don't want to do in-path completion.
@@ -101,12 +126,6 @@
   ignore=(-F fignore)
 fi
 
-# If we weren't given any file patterns as arguments, we trick ourselves
-# into believing that we were given the pattern `*'. This is just to simplify
-# the following code.
-
-[[ -z "$1" ]] && 1='*'
-
 # Now let's have a closer look at the string to complete.
 
 if [[ "$str[1]" = \~ ]]; then
@@ -205,9 +224,8 @@
       # complete and the glob patterns we were given as arguments.
 
       collect=()
-      suffixes=( $rest$@ )
+      suffixes=( $rest$^pats )
       suffixes=( "${(@)suffixes:gs.**.*.}" )
-      [[ -n $comp_dirs ]] && suffixes=( ${suffixes}"(-/)" )
 
       # In the loop the prefixes from the `tmp1' array produced above and
       # the suffixes we just built are used to produce possible matches
@@ -248,7 +266,7 @@
 	# (the `-f' and `-F' options).
 
         for i in $collect; do
-          compadd -p "$linepath$testpath" -W "$tmp1" -s "/${i#*/}" -f "$ignore[@]" - "${i%%/*}"
+          compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" -p "$linepath$testpath" -W "$tmp1" -s "/${i#*/}" -f "$ignore[@]" - "${i%%/*}"
         done
 
 	# We have just finished handling all the matches from above, so we
@@ -277,9 +295,13 @@
   # can produce in this directory, if any.
 
   tmp1="$prepath$realpath$testpath"
-  suffixes=( $str$@ )
+  suffixes=( $str$^pats )
   suffixes=( "${(@)suffixes:gs.**.*.}" )
-  [[ -n $comp_dirs ]] && suffixes=( ${suffixes}"(-/)" )
   tmp2=( ${~tmp1}${~matchflags}${~suffixes} )
-  compadd -p "$linepath$testpath" -W "$prepath$realpath$testpath" -f "$ignore[@]" - ${tmp2#$tmp1}
+  if [[ $#tmp2 -eq 0 && "$sopt" = */* ]]; then
+    [[ "$testpath[-1]" = / ]] && testpath="$testpath[1,-2]"
+    compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" -f - "$linepath$testpath"
+  else
+    compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" -p "$linepath$testpath" -W "$prepath$realpath$testpath" -f "$ignore[@]" - ${(@)tmp2#$tmp1}
+  fi
 done
diff -u of/Completion/init Functions/Completion/init
--- of/Completion/init	Wed Feb 24 15:11:42 1999
+++ Functions/Completion/init	Thu Feb 25 09:14:32 1999
@@ -63,16 +63,15 @@
 # If given the `-a' option, the function is defined as being autoloaded.
 
 defcomp() {
-  local name autol new
+  local opt name autol new
 
-  if [[ "$1" = -n ]]; then
-    shift
-    new=yes
-  fi
-  if [[ "$1" = -a ]]; then
-    shift
-    autol=yes
-  fi
+  while getopts "na" opt; do
+    case "$opt" in
+    a) autol=yes;;
+    n) new=yes;;
+    esac
+  done
+  shift OPTIND-1
   if [[ $# -eq 1 ]]; then
     if [[ -z "$new" || "${+comps[$1]}" -eq 0 ]]; then
       comps[$1]="_$1"

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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