zsh-users
 help / color / mirror / code / Atom feed
* Completion for gtar
@ 1998-08-25 15:29 Bruce Stephens
  1998-08-25 17:48 ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Bruce Stephens @ 1998-08-25 15:29 UTC (permalink / raw)
  To: zsh-users

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.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Completion for gtar
  1998-08-25 15:29 Completion for gtar Bruce Stephens
@ 1998-08-25 17:48 ` Bart Schaefer
  1998-08-25 18:23   ` error value from pipe Stephen Ng
  1998-08-26 10:12   ` Completion for gtar Bruce Stephens
  0 siblings, 2 replies; 5+ messages in thread
From: Bart Schaefer @ 1998-08-25 17:48 UTC (permalink / raw)
  To: Bruce Stephens, zsh-users

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 ~/<TAB>
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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* error value from pipe
  1998-08-25 17:48 ` Bart Schaefer
@ 1998-08-25 18:23   ` Stephen Ng
  1998-08-26 10:12   ` Completion for gtar Bruce Stephens
  1 sibling, 0 replies; 5+ messages in thread
From: Stephen Ng @ 1998-08-25 18:23 UTC (permalink / raw)
  To: zsh-users

I have an enhancement request for zsh:

When piping a series of commands, e.g.

cat X | sort 

zsh apparently only lets you access the error status of the last 
command in the pipe; I need to know if any command in the pipe 
has failed.  

(Bash will let you access the error codes for any command in the 
pipe as an array, which is overkill for me--I just need to know if any 
of the commands returned a non-zero value.)

Stephen Ng


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Completion for gtar
  1998-08-25 17:48 ` Bart Schaefer
  1998-08-25 18:23   ` error value from pipe Stephen Ng
@ 1998-08-26 10:12   ` Bruce Stephens
  1 sibling, 0 replies; 5+ messages in thread
From: Bruce Stephens @ 1998-08-26 10:12 UTC (permalink / raw)
  To: zsh-users

"Bart Schaefer" <schaefer@brasslantern.com> writes:

> 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.

No, I hadn't.  Partly deliberately---this was as much an exercise as
anything.  Now I look at it, and the two look reassuringly similar,
although PWS's provides more.

> You can just do
> 
> 	compctl -f -x 'p[1]' -k taropts -- gtar
> 
> unless you want to unset taropts and not have it hanging around.

Yes.  Or rather, I didn't want to rely on taropts sticking around.

> 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 ~/<TAB>
> zsh% gtar zxf ~/-
> 
> even when there's no file named "-" in your home dir.

That's clearly not what I want.  You're right, there's no advantage in
having - complete to itself, so I ought to remove it.

> 	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.

I don't care about not having the f option---I never use gtar except
on files.  (Backups and so on are done differently, and by somebody
else.)

> 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.

OK.  I don't think this is clear from the documentation.  Not as clear
as the two paragraphs you've just given, anyway.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Completion for gtar
       [not found] <199808260818.KAA00478@beta.informatik.hu-berlin.de>
@ 1998-08-26 10:05 ` Bruce Stephens
  0 siblings, 0 replies; 5+ messages in thread
From: Bruce Stephens @ 1998-08-26 10:05 UTC (permalink / raw)
  To: zsh-users

Sven Wischnowsky <wischnow@informatik.hu-berlin.de> writes:

> Or you return an empty reply array and use xor'ed completion:
> 
>      - 'p[3,-1] W[1,*x*] W[2,^-]' -K gtar_files + -f -- gtar
>                                                ^^^^^^

I see.  I was wondering how the gtar_files could indicate failure, but
it ought to have been obvious that returning an empty array is the
thing to do.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1998-08-26 10:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-08-25 15:29 Completion for gtar Bruce Stephens
1998-08-25 17:48 ` Bart Schaefer
1998-08-25 18:23   ` error value from pipe Stephen Ng
1998-08-26 10:12   ` Completion for gtar Bruce Stephens
     [not found] <199808260818.KAA00478@beta.informatik.hu-berlin.de>
1998-08-26 10:05 ` Bruce Stephens

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).