Subject: Re: PATCH: short-circuiting glob exclusion operator
From: Mikael Magnusson <[email-masked]>
To: Peter Stephenson <[email-masked]>
Cc: "Zsh Hackers' List" <[email-masked]>
Date: Mon, 21 Mar 2016 21:39:07 +0100
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Mon, Mar 21, 2016 at 7:36 PM, Peter Stephenson
<[email-masked]> wrote:
> This is a request for comments for now.  I'm not yet entirely sure the
> pattern syntax with two tildes isn't going to cause problems (though I
> don't see what they would be), or that I've identified all the side
> effects that can happen.
>
> As an ultra brief summary, ~~ in a glob introduces a pattern that will
> prune directories on the way through in addition to acting in the normal
> exclusion fashion.  So **/*~~*/foo stops at and ignores any directories
> called foo at any level(#1) on the way down.  This is unlike a single
> tilde where exclusions are only performed after the complete set of
> matches is generated, so it's potentially much more efficient.
>
> (#1) Except the top.  It's a bit anhoying you need  (|*/).

Is it like (^foo/)##* then, except possibly easier to combine with
other patterns, and/or to stop on more complicated expressions? I
assume you could do **/*~~*/foo/(|*/)bar where * also can match across
multiple slashes to stop recursing in bar directories if we're already
in a foo directory. It's not immediately obvious to me how to achieve
that with (^foo/)##* so it's probably not possible ;).

Here's a possible problem with double tilde as the syntax:

% touch foo~ hi~ hello
% echo *~~hi*
foo~

If ~~ was special, this would mean * with hi* removed, and print hello
foo~ instead of just foo~, which could break existing users. Or more
dramatically like in this fictional example,

# remove all backup files except some I
# like to keep for plot purposes
rm *~~importantfile*

With the change this would wipe out both backups and originals.

-- 
Mikael Magnusson