From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 712 invoked from network); 25 Aug 1998 17:59:22 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 25 Aug 1998 17:59:22 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id NAA17951; Tue, 25 Aug 1998 13:48:21 -0400 (EDT) Resent-Date: Tue, 25 Aug 1998 13:48:04 -0400 (EDT) From: "Bart Schaefer" Message-Id: <980825104831.ZM15886@candle.brasslantern.com> Date: Tue, 25 Aug 1998 10:48:31 -0700 In-Reply-To: Comments: In reply to Bruce Stephens "Completion for gtar" (Aug 25, 4:29pm) References: X-Mailer: Z-Mail (4.0b.820 20aug96) To: Bruce Stephens , zsh-users@math.gatech.edu Subject: Re: Completion for gtar MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Resent-Message-ID: <"jHJhY2.0._N4.JZlur"@math> Resent-From: zsh-users@math.gatech.edu X-Mailing-List: archive/latest/1754 X-Loop: zsh-users@math.gatech.edu X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu On Aug 25, 4:29pm, Bruce Stephens wrote: } Subject: Completion for gtar Have you looked at PWS's tar completion in Misc/compctl-examples in 3.1.4? It even has a function to extract completable file names from the tar file. } So, a quick approach is to complete the first argument specially, and } have the rest just as files: } } taropts=({z,}{t,x,c}{v,}{p,}f) } compctl -f -x 'p[1]' -k "($taropts)" -- gtar You can just do compctl -f -x 'p[1]' -k taropts -- gtar unless you want to unset taropts and not have it hanging around. } Here, I want to match either a -, or any file } (anywhere in the filestore) ending in .tar.gz or .tar.Z. -g allows } several patterns separated by spaces, so that's not a problem. I don't think that means what you think it means. If you put the "-" in the list of -g patterns, then it's treated as a file name. It just so happens that, because it has no wildcards, it never gets dropped from the list of completions. So you'll find that you can complete e.g. like this: zsh% gtar zxf ~/ zsh% gtar zxf ~/- even when there's no file named "-" in your home dir. If you think you need to complete "-" (which boggles me, as it's only one character; just type it!) you probably want: compctl -f -x 'p[1]' -k taropts \ - 'p[2] W[1,*z*]' -/g '*.tar.(gz|Z)' -k '(-)' \ -- gtar BTW, don't you want to add W[1,*f*] to that? You don't want to complete file names if there's no "f" option. } My first guess, using -g '**/*.tar.(gz|Z)' doesn't work at all well: } it's really slow. Obviously my thinking was wrong. Zsh handles all the path completion for you internally, so you don't need the **/ unless you want to have a single TAB complete tarfile names that are some unknown number of intervening directories below the current directory. The -g pattern is matched against files in the directory to which you have completed so far, so you only need the tail. } compctl -f -x 'p[1]' -k "($taropts)" \ } - 'p[2] W[1,*z*]' -/g '- *.tar.(gz|Z)' \ } - 'p[2] W[1,^*z*]' -/g '- *.tar' -- gtar } } And another thing: why isn't there any sense of exclusive ors? All -x options are exclusive, or more accurately, they're short-circuited. So as soon as 'p[2] W[1,*z*]' has matched, no other -x pattern is tried. Thus you could have written: compctl -f -x 'p[1]' -k taropts \ - 'p[2] W[1,*z*] W[1,*f*]' -/g '*.tar.(gz|Z)' -k '(-)' \ - 'p[2] W[1,*f*]' -/g '*.tar' -k '(-)' \ -- gtar } How can I best express this kind of thing? Is this what alternation } is about? That is what alternation is about, but alternation works differently. The -x branches are short-circuited on whether their patterns match, so once you take a -x branch you can never see completions from any of the other branches, even if no completions result from the branch where the patterns matched. Alternation with "+", on the other hand, short-circuits on whether the list of possible completions is empty, so it'll keep trying until it runs out of alternatives or finds one that produces something. } Lastly, sometimes I want to extract specific files from a tarfile, so } it would be nice for completion to be available for that (using a } function, in this case, but perhaps I could use -s in some wacky } fashion?). You can't really use -s because there's no way to get at the other parts of the command line (to get the name of the tarfile itself) during the -s expansion. } The "read -Ac args" isn't entirely obvious from the docs. There probably should be mention of -A made under the -c description. } The function just lists the files in the archive (which is, } confusingly, the third in the args array, but the second argument in } the compctl pattern). Similarly, the check to see whether the archive } is compressed or not has to check $args[2], whereas it's 'p[1]' in the } compctl. Add to the function setopt localoptions ksharrays and then $args[1] and -x 'p[1]' will match up. There may be some other ksh array behavior that you don't want, though, so .... } And how can I arrange a fallback: suppose the archive } doesn't exist---how can I get the equivalent of -f or something in } this case? Do I write } } reply=($1*$2*) } } or something? (Setting NULL_GLOB as a local option in the function.) Yes, that should do it. } I'm not sure how this feeds back to the compctl discussion (on } zsh-workers). Additions discussed on zsh-workers would include letting you "factor out" the -k '(-)' from the last of my examples above. Otherwise there isn't much that overlaps. } Specifying a file matching a pattern is a bit strange: -/g '*.gz'. As I said in another post, the -/ is one option (match directories), the -g is another. } I don't think it's clear how the arguments are numbered. In the } compctl, is -1 the last argument? Yes. } I assume it is, or is it 0? 0 is the command name. } In the function, I just guessed at the numbering. Zsh array indices are 1-based, so when you read the input line into args with `read -Ac args` you've put the command (compctl position 0) into the first array element (array index 1). If you setopt ksharrays, the array indices become 0-based, the same as the compctl. In all cases, numbering from the "wrong" end -1,-2,etc. starts with the last argument. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com