From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7497 invoked from network); 25 Aug 1998 15:40:55 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 25 Aug 1998 15:40:55 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id LAA14389; Tue, 25 Aug 1998 11:31:46 -0400 (EDT) Resent-Date: Tue, 25 Aug 1998 11:31:08 -0400 (EDT) Sender: B.Stephens@isode.com To: zsh-users@math.gatech.edu Subject: Completion for gtar Mime-Version: 1.0 (generated by tm-edit 7.108) Content-Type: text/plain; charset=US-ASCII From: Bruce Stephens Date: 25 Aug 1998 16:29:59 +0100 Message-ID: X-Mailer: Gnus v5.6.27/XEmacs 20.4 - "Emerald" Resent-Message-ID: <"S_T9p3.0.AW3.xYjur"@math> Resent-From: zsh-users@math.gatech.edu X-Mailing-List: archive/latest/1753 X-Loop: zsh-users@math.gatech.edu X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu Well, I've had a proper play with completion (while waiting for a long recompile), and come up with this completion pattern for the things I most often do with gtar. This certainly doesn't do everything---it just fills in a few bits that I've found irritating. 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 taropts expands to: ztvpf ztvf ztpf ztf zxvpf zxvf zxpf zxf zcvpf zcvf zcpf zcf tvpf tvf tpf tf xvpf xvf xpf xf cvpf cvf cpf cf of course. A next obvious idea is to complete the second argument specially: compctl -f -x 'p[1]' -k "($taropts)" \ - 'p[2] W[1,*z*]' -g '- *.tar.(gz|Z) *(-/)' \ - 'p[2] W[1,^*z*]' -g '- *.tar *(-/)' -- gtar Yuck. After matching the 'p[2] W[1,*z*]', how do I say there are a few possibilities? 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. My first guess, using -g '**/*.tar.(gz|Z)' doesn't work at all well: it's really slow. Obviously my thinking was wrong. Ah, I see. Obviously the - is special (so I can't say "-g - -g '*.tar'"), but I *can* have multiple options. So in this case, I can write: compctl -f -x 'p[1]' -k "($taropts)" \ - 'p[2] W[1,*z*]' -/g '- *.tar.(gz|Z)' \ - 'p[2] W[1,^*z*]' -/g '- *.tar' -- gtar which is a little clearer. And I can also stick -k options and things: compctl -x 'p[1]' -/g '*.gz' -k "(a b c)" -- foo This will have the first argument to foo expanding to .gz files (anywhere), or a, b or c. And another thing: why isn't there any sense of exclusive ors? The second two lines are exclusive: either the second argument contains a z (and I want to match compressed files) or it doesn't (and I don't). How can I best express this kind of thing? Is this what alternation is about? 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?). compctl -f -x 'p[1]' -k "($taropts)" \ - 'p[2] W[1,*z*]' -/g '- *.tar.(gz|Z)' \ - 'p[2] W[1,^*z*]' -/g '- *.tar' \ - 'p[3,-1] W[1,*x*] W[2,^-]' -K gtar_files -- gtar I don't want to try listing archives from stdin, hence the W[2,^-]. And the function: function gtar_files { local args opt read -Ac args if [[ $args[2] == *z* ]]; then opt=ztf else opt=tf fi reply=($(gtar $opt $args[3])) } The "read -Ac args" isn't entirely obvious from the docs. It's pretty clear from looking at the examples. 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. 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.) I'm not sure how this feeds back to the compctl discussion (on zsh-workers). The structure is a bit confusing---I haven't used alternation here, and I'm not sure how it fits into the rest. Specifying a file matching a pattern is a bit strange: -/g '*.gz'. I can live with it, though. Perhaps it ought to be mentioned in the documentation, so it's more obvious that that's what you're supposed to do, since this is a really common thing to want to do. I guess the very end of 4.2 of the FAQ sort of mentions it, but I missed it at first reading. I don't think it's clear how the arguments are numbered. In the compctl, is -1 the last argument? I assume it is, or is it 0? In the function, I just guessed at the numbering.