diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:20:19 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:20:19 +0000 |
commit | 04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8 (patch) | |
tree | 2215f99f95d55660fc939a029bf965c454d080b5 /Completion/User/_tar | |
parent | 7a0415cfd70a02b2280d27556c6c54cef1c86e1a (diff) | |
download | zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.tar.gz zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.tar.xz zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.zip |
zsh-3.1.5-pws-12 zsh-3.1.5-pws-12
Diffstat (limited to 'Completion/User/_tar')
-rw-r--r-- | Completion/User/_tar | 162 |
1 files changed, 109 insertions, 53 deletions
diff --git a/Completion/User/_tar b/Completion/User/_tar index 84c490f1e..d11ee76c8 100644 --- a/Completion/User/_tar +++ b/Completion/User/_tar @@ -1,69 +1,125 @@ #defcomp tar # Tar completion. Features: -# - Assumes tar commands are in second position, tar archive is in third -# e.g. tar xvzf zsh-3.0.5.tar.gz ... -# Could search better. Send me the patch. +# - Tries to collect tar commands from second position, single letter +# option, and long options. # - `tar' can be called anything, will use the correct name -# - Preferentially completes *.tar and *.TAR files in third position -# - unless z or Z appears in the commands, in which case prefer *.tar.gz -# and similar (GNU tar). -# - From fourth position on, if command is x or t, completes files inside -# archive. This is supposed to look pretty much as if the files are -# in an ordinary directory hierarchy. Handles extraction from compressed -# archives (GNU tar). +# - Uses the function `_tar_archive' to complete archive files. +# - Tries to find out if compressed archives should be used. +# - Completes files inside archive. This is supposed to look pretty +# much as if the files are in an ordinary directory hierarchy. +# Handles extraction from compressed archives (GNU tar). # - Anywhere -- appears, gets a list of long options to complete from -# tar itself (GNU tar); this needs perl. If you have GNU tar but not -# perl: your system manager is weird. +# tar itself (GNU tar) # - Things like --directory=... are also completed correctly. emulate -LR zsh setopt extendedglob -local nm=$NMATCHES tcmd="$words[2]" tf="$words[3]" +local _tar_cmd tf tmp del -if [[ $PREFIX = *=* ]]; then - # For GNU tar arguments like --directory= - IPREFIX=${PREFIX%%\=*}= - PREFIX=${PREFIX#*=} - if [[ $IPREFIX = --directory* ]]; then - _path_files -/ - else - _files +# First we collect in `_tar_cmd' single letter options describing what +# should be done with the archive and if it is compressed. This +# collected from options arguments that start with only one hyphen, +# from some of the possible long options, and from the second word if +# that does not start with a hyphen. + +tmp=("${(@M)words:#-[^-]*}") +_tar_cmd="${(j::)tmp#-}" + +(( $words[(I)--(un|)gzip] )) && _tar_cmd="z$_tar_cmd" +(( $words[(I)--(un|)compress] )) && _tar_cmd="Z$_tar_cmd" +(( $words[(I)--list] )) && _tar_cmd="t$_tar_cmd" +(( $words[(I)--(extract|get)] )) && _tar_cmd="x$_tar_cmd" +(( $words[(I)--create] )) && _tar_cmd="c$_tar_cmd" + +# Other ways of finding out what we're doing: first +# look in the first argument if it's not an option +if [[ "$words[2]" = *[txcdruA]*~-* ]]; then + _tar_cmd="$words[2]$_tar_cmd" +elif [[ $_tar_cmd != *[txcdruA]* && CURRENT -gt 2 ]]; then + # look for more obscure long options: these aren't all handled. + (( $words[(I)--(diff|compare)] )) && _tar_cmd="d$_tar_cmd" + (( $words[(I)--append] )) && _tar_cmd="r$_tar_cmd" + (( $words[(I)--update] )) && _tar_cmd="u$_tar_cmd" + (( $words[(I)--(con|)catenate] )) && _tar_cmd="A$_tar_cmd" + (( $words[(I)--delete] )) && del=1 +fi + +# Next, we try to find the archive name and store it in `tf'. The name +# is searched after a `--file=' long option, in the third word if the +# second one didn't start with a hyphen but contained a `f', and after +# an option argument starting with only one hyphen and containing a `f'. + +tmp="$words[(I)--file=*]" +if (( tmp )); then + tf="${words[tmp][8,-1]}" + _tar_cmd="f$_tar_cmd" +elif [[ "$words[2]" != -* && "$words[2]" = *f* ]]; then + tf="$words[3]" + _tar_cmd="f$_tar_cmd" +else + tmp="${words[(I)-*f*~--*]}" + if (( tmp )); then + tf="$words[tmp+1]" + _tar_cmd="f$_tar_cmd" fi -elif [[ $PREFIX = --* ]]; then - # gnu tar, generate completions from --help - # ones followed by = get that as a suffix - local -a ownlist eqlist - local comp - $words[1] --help | - perl -ne 'while (/--[^[\s,='\'']+=?/g) { print "$&\n"; }' | - while read comp; do - if [[ $comp = *= ]]; then - eqlist[$#eqlist+1]=${comp%=} - else - ownlist[$#ownlist+1]=$comp - fi - done - compgen -S '=' -k eqlist - compgen -k ownlist -elif [[ "$tcmd" = *[tx]*f* && $CURRENT -ge 4 ]] then - # Listing or extracting a particular file. We run `tar t...' - # on the file, keeping the list of filenames cached, plus the - # name of the tarfile so we know if it changes. +fi + +# Now we complete... + +if [[ "$PREFIX" = --* ]]; then + + # ...long options after `--'. + + _long_options '--owner*' "_tilde" \ + '*=(PROG|COMMAND)*' "_command_names" \ + '*=ARCHIVE*' "_tar_archive" \ + '*=CONTROL*' "[t numbered nil existing never simple]" + +elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* && + "$words[CURRENT-1]" != --* ) || + ( CURRENT -eq 3 && "$words[2]" = *f* && "$words[2]" != -* ) ]]; then + + # ...archive files if we think they are wanted here. + + _tar_archive + +elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then + + # ...and files from the archive if we found an archive name and tar + # commands. We run `tar t...' on the file, keeping the list of + # filenames cached, plus the name of the tarfile so we know if it + # changes. + local largs=-tf - [[ $words[2] = *z* ]] && largs=-tzf - [[ $words[2] = *Z* ]] && largs=-tZf - if [[ $tf != $tar_cache_name ]]; then - tar_cache_list=("${(@f)$($words[1] $largs $tf)}") - tar_cache_name=$tf + if [[ $_tar_cmd = *z* ]]; then + largs=-tzf + elif [[ $_tar_cmd = *Z* ]]; then + largs=-tZf + else + # Some random compression program e.g. bzip2 + tmp="${words[(r)--use-comp*]}" + [[ -n $tmp ]] && largs=($tmp -tf) + fi + + if [[ $tf != $_tar_cache_name ]]; then + _tar_cache_list=("${(@f)$($words[1] $largs $tf)}") + _tar_cache_name=$tf + fi + + _multi_parts / _tar_cache_list +else + + # See if we should use a path prefix. We have to use eval as the dir can + # be any unevaluated thing which appears on the command line, including a + # parameter. + tmp=${words[(r)--dir[a-z]#=*]} + if [[ -n $tmp ]]; then + eval "tmp=(${tmp#*=})" + _path_files -W tmp + else + _files fi - _multi_parts / tar_cache_list -elif [[ "$tcmd" = *c*f* && $CURRENT -ge 4 ]] then - _files -elif [[ "$tcmd" = *[zZ]*f* && $CURRENT -eq 3 ]] then - _files -g '*.((tar|TAR).(gz|Z)|.tgz)' -elif [[ "$tcmd" = *f* && $CURRENT -eq 3 ]] then - _files -g '*.(tar|TAR)' fi |