zsh-users
 help / color / mirror / code / Atom feed
* Use of (e:...:) glob qualifier with _files -g?
@ 2019-11-04  6:08 Chris Nebel
  2019-11-04  6:56 ` dana
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Nebel @ 2019-11-04  6:08 UTC (permalink / raw)
  To: zsh-users

In an attempt to get my darwinup completer to only complete actual archive files, I’ve been playing with the shell code glob qualfiers.  For example, this will match everything file(1) says is an archive of some sort:

	*(e:'file -bz $REPLY | grep -wq archive')

Works great at the shell prompt, but I have been unable to use it — or pretty much any (e:…:) expression — with “_files -g”.  Since it seems to break as soon as I have a space in the expression, I suspect it’s some sort of quoting problem, but I’m stumped for a solution.  I do have a workaround, which is to define a function and use the “+” qualifier instead:

	_is_darwinup_root () {
	    file -bz $REPLY | grep -wq archive
	}

	_darwinup_roots () {
	    _files -g '*(+_is_darwinup_root)'
	}

…but that means one more global-namespace function that I’d rather not have.  Any tips?


—Chris N.

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

* Re: Use of (e:...:) glob qualifier with _files -g?
  2019-11-04  6:08 Use of (e:...:) glob qualifier with _files -g? Chris Nebel
@ 2019-11-04  6:56 ` dana
  2019-11-04 20:41   ` Chris Nebel
  0 siblings, 1 reply; 5+ messages in thread
From: dana @ 2019-11-04  6:56 UTC (permalink / raw)
  To: Chris Nebel; +Cc: zsh-users

On 4 Nov 2019, at 00:08, Chris Nebel <c.nebel@mac.com> wrote:
> *(e:'file -bz $REPLY | grep -wq archive')

I'm not sure that's even a good idea. You'd be running an external process
against every single file the function encountered. On network drives or in
directories with many files that could take a while.

Also, i've never used darwinup, but it looks to me like it supports only a
select number of archive formats, which are guessed based on the file
extension and enumerated here:

https://github.com/macosforge/darwinbuild/blob/master/darwinup/Archive.cpp#L323

If that's the case, you should be able to just use '*.(tar|zip|whatever)',
which is much simpler and faster.

With that said, to answer your actual question, i think the reason it doesn't
work is that _files has an undocumented feature where if it detects unescaped
white space in the pattern it assumes that you're trying to supply *multiple*
patterns to be transformed into a brace expansion. Maybe there is some very
fancy quoting you can do to make that work, but at that point i think using
the + qualifier would be easier.

dana


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

* Re: Use of (e:...:) glob qualifier with _files -g?
  2019-11-04  6:56 ` dana
@ 2019-11-04 20:41   ` Chris Nebel
  2019-11-04 20:50     ` Chris Nebel
  2019-11-04 21:24     ` Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: Chris Nebel @ 2019-11-04 20:41 UTC (permalink / raw)
  To: zsh-users

Ok, fair.  I’ve been worried that while on the one hand I’d like to complete only supported archive files, on the other hand people use all sorts of mutant extensions for them, especially when compressed, hence just sniffing the file contents.  However, a not-terribly-complicated pattern will cover a lot of the cases.

My problem then becomes how to let people configure the completion so they can use any extensions I didn’t cover.  I’m guessing that the answer has something to do with zstyle and the “file-patterns” style, but I’m having trouble turning the examples in zshcompsys(1) into something that works.  To make this a bit more concrete, say my completion code looks something like this:

	files -g '*.(cpio|tar|xar)'

…and someone wants to also match “*.cpgz” files, what would they do?


—Chris N.

> On Nov 3, 2019, at 10:56 PM, dana <dana@dana.is> wrote:
> 
> On 4 Nov 2019, at 00:08, Chris Nebel <c.nebel@mac.com> wrote:
>> *(e:'file -bz $REPLY | grep -wq archive')
> 
> I'm not sure that's even a good idea. You'd be running an external process
> against every single file the function encountered. On network drives or in
> directories with many files that could take a while.
> 
> Also, i've never used darwinup, but it looks to me like it supports only a
> select number of archive formats, which are guessed based on the file
> extension and enumerated here:
> 
> https://github.com/macosforge/darwinbuild/blob/master/darwinup/Archive.cpp#L323
> 
> If that's the case, you should be able to just use '*.(tar|zip|whatever)',
> which is much simpler and faster.
> 
> With that said, to answer your actual question, i think the reason it doesn't
> work is that _files has an undocumented feature where if it detects unescaped
> white space in the pattern it assumes that you're trying to supply *multiple*
> patterns to be transformed into a brace expansion. Maybe there is some very
> fancy quoting you can do to make that work, but at that point i think using
> the + qualifier would be easier.
> 
> dana
> 


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

* Re: Use of (e:...:) glob qualifier with _files -g?
  2019-11-04 20:41   ` Chris Nebel
@ 2019-11-04 20:50     ` Chris Nebel
  2019-11-04 21:24     ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Chris Nebel @ 2019-11-04 20:50 UTC (permalink / raw)
  To: zsh-users

And I actually didn’t realize this until you pointed me to the source, but darwinup *will not install* anything with an extension it doesn’t know about — it never tries to sniff the file contents.  So, I really do have a finite list to deal with, and can just list them all.  I’m still curious to know the answer to the zstyle question, though.

—Chris N.

> On Nov 4, 2019, at 12:41 PM, Chris Nebel <c.nebel@mac.com> wrote:
> 
> Ok, fair.  I’ve been worried that while on the one hand I’d like to complete only supported archive files, on the other hand people use all sorts of mutant extensions for them, especially when compressed, hence just sniffing the file contents.  However, a not-terribly-complicated pattern will cover a lot of the cases.
> 
> My problem then becomes how to let people configure the completion so they can use any extensions I didn’t cover.  I’m guessing that the answer has something to do with zstyle and the “file-patterns” style, but I’m having trouble turning the examples in zshcompsys(1) into something that works.  To make this a bit more concrete, say my completion code looks something like this:
> 
> 	files -g '*.(cpio|tar|xar)'
> 
> …and someone wants to also match “*.cpgz” files, what would they do?
> 
> 
> —Chris N.
> 
>> On Nov 3, 2019, at 10:56 PM, dana <dana@dana.is> wrote:
>> 
>> On 4 Nov 2019, at 00:08, Chris Nebel <c.nebel@mac.com> wrote:
>>> *(e:'file -bz $REPLY | grep -wq archive')
>> 
>> I'm not sure that's even a good idea. You'd be running an external process
>> against every single file the function encountered. On network drives or in
>> directories with many files that could take a while.
>> 
>> Also, i've never used darwinup, but it looks to me like it supports only a
>> select number of archive formats, which are guessed based on the file
>> extension and enumerated here:
>> 
>> https://github.com/macosforge/darwinbuild/blob/master/darwinup/Archive.cpp#L323
>> 
>> If that's the case, you should be able to just use '*.(tar|zip|whatever)',
>> which is much simpler and faster.
>> 
>> With that said, to answer your actual question, i think the reason it doesn't
>> work is that _files has an undocumented feature where if it detects unescaped
>> white space in the pattern it assumes that you're trying to supply *multiple*
>> patterns to be transformed into a brace expansion. Maybe there is some very
>> fancy quoting you can do to make that work, but at that point i think using
>> the + qualifier would be easier.
>> 
>> dana
>> 
> 


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

* Re: Use of (e:...:) glob qualifier with _files -g?
  2019-11-04 20:41   ` Chris Nebel
  2019-11-04 20:50     ` Chris Nebel
@ 2019-11-04 21:24     ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2019-11-04 21:24 UTC (permalink / raw)
  To: Chris Nebel; +Cc: zsh-users

On Mon, Nov 4, 2019 at 2:42 PM Chris Nebel <c.nebel@mac.com> wrote:
>
> My problem then becomes how to let people configure the completion so they can use any extensions I didn’t cover.  I’m guessing that the answer has something to do with zstyle and the “file-patterns” style, but I’m having trouble turning the examples in zshcompsys(1) into something that works.  To make this a bit more concrete, say my completion code looks something like this:
>
>         files -g '*.(cpio|tar|xar)'
>
> …and someone wants to also match “*.cpgz” files, what would they do?

Typically you would assign the pattern to a variable, and then use a
style to allow the user to substitute his own value for that variable.
You can name the style anything you like, but a usual approach would
be to choose a name that is already in use for similar purposes.  If
you call the existing _files completer it will handle the zstyle
lookup.

You need to determine a context name for your completion and assign
that to a local variable named curcontext to inform other functions
that look for styles of the context in which they are being invoked.

To put this together, you'd simply do something like:

local curcontext="${curcontext%:*:*}:darwinup"
_files -g '*.(cpio|tar|xar)'

Then a user can write

zstyle ':completion:*:darwinup' file-patterns "%p *.cpgz”

where %p will be replaced by your defaults and *.cpgz will also be
tried (see previous remarks about why spaces are complicated).

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

end of thread, other threads:[~2019-11-04 21:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-04  6:08 Use of (e:...:) glob qualifier with _files -g? Chris Nebel
2019-11-04  6:56 ` dana
2019-11-04 20:41   ` Chris Nebel
2019-11-04 20:50     ` Chris Nebel
2019-11-04 21:24     ` Bart Schaefer

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