From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1551 invoked from network); 25 Feb 1999 11:09:20 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 25 Feb 1999 11:09:20 -0000 Received: (qmail 4041 invoked by alias); 25 Feb 1999 11:08:54 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 5521 Received: (qmail 20746 invoked from network); 25 Feb 1999 10:18:08 -0000 Date: Thu, 25 Feb 1999 11:17:26 +0100 (MET) Message-Id: <199902251017.LAA29194@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Peter Stephenson's message of Wed, 24 Feb 1999 18:03:36 +0100 Subject: 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/ 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 ' option as with `compctl' and `complist', -# but only as the first argument. -# -# This function also accepts an optional `-F ' option as its first -# argument or just after the `-W '. 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 ', `-J ', +# `-V ', `-W paths', and `-F '. All but the last have the +# same syntax and meaning as for `complist'. The `-F ' 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@informatik.hu-berlin.de