Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zstyle: "more specific" patterns and *-components



Roman Perepelitsa wrote on Mon, 27 Apr 2020 18:10 +0200:
> On Mon, Apr 27, 2020 at 12:15 PM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx> wrote:
> >
> > WDYT?
> 
> My reading of the documentation matches yours, so I also expected the
> behavior you expected (which isn't the actual behavior). I also find
> the documented behavior preferable to the actual behavior.
> 

I'm not sure what I prefer, actually.  The documentation disagrees with
the implementation, but I'm wary of changing the implementation to match
the documentation because that seems like it could introduce
hard-to-diagnose behaviour changes upon upgrading.

I reviewed my own settings (via the output of «zstyle» without
arguments) and found only one case in which a context could be matched
by two different patterns, and even that was a bug in my zshrc (one of
the patterns was insufficiently specific), so maybe I'm being overly
careful here.

Does anyone else have zstyle settings such that a single lookup (of
a particular style under a particular context) could be matched by
multiple patterns?

Mikael Magnusson wrote on Mon, 27 Apr 2020 19:38 +0200:
> On 4/27/20, Roman Perepelitsa <roman.perepelitsa@xxxxxxxxx> wrote:
> > On Mon, Apr 27, 2020 at 12:15 PM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
> > wrote:
> >>
> >> WDYT?
> >
> > My reading of the documentation matches yours, so I also expected the
> > behavior you expected (which isn't the actual behavior). I also find
> > the documented behavior preferable to the actual behavior.
> >
> > My experience with zstyle is minuscule, so appraising my opinion at 2
> > cents would be too generous.
> 
> Another view is that in both cases you specified the values of two
> 'elements', the fact that they are adjacent in one case shouldn't (one
> could argue) affect the specificity of the pattern. (this isn't
> necessarily my view).

If we change the implementation to match the documentation and Alice
wishes for both patterns to be considered equally specific, she will be
able to achieve that by explicitly specifying all colons in the patterns:

    zstyle ':foo:bar:*:*' lorem world
    zstyle ':foo:*:baz:*' lorem hello

On the other hand, if we change the documentation to match the
implementation and Alice wants one of the patterns to be considered more
specific regardless of the order the two patterns are defined in, she
can achieve that by using a pattern other than «*» that matches the same
things «*» would:

    zstyle ':foo:bar:*'      lorem world
    zstyle ':foo:*:baz:*(|)' lorem hello

(This works because the pattern «*(|)» is considered more specific — and
gets a higher score — than the pattern «*».)

dana wrote on Mon, 27 Apr 2020 13:54 -0500:
>   I'm guessing that * is weighted 0 so that :foo:* doesn't have more weight
>   than :foo:, but could it work better? For example, might it work to change
>   the weighting to this:
> 
>     0  First consecutive *-only component (first * in :foo:*:*:bar*)
>     1  Subsequent consecutive *-only component (second * in :foo:*:*:bar*)
>     2  Pattern component (bar* in :foo:*:*:bar*)
>     3  Literal component (foo in :foo:*:*:bar*)
> 
>   ?
> 
> But i don't think my suggested change will fix the case you described. Maybe
> give each *-only component a weight of 1 unless it's at the very end? Haven't
> really thought about it since i wrote that, so there might be other
> considerations

Firstly, shouldn't we choose between the implemented semantics and the
documented semantics?  Changing to a third semantics seems too
xkcd.com/927/-ey to me: it risks causing breakage _both_ to people who
relied on the documented behaviour and to people who relied on the
implemented behaviour.

I don't immediately see the rationale behind your proposed scoring.  The
two patterns you mention, «:foo» and «:foo:*», don't seem parallel to
each other, since there's no possible context that can be matched by
both of them.

Regarding the option of changing the implementation to match the
documentation, I interpret the documentation to mean a pattern that has
more colons than another is always considered more specific, period.
That could be implemented as a «struct { unsigned number_of_colons;
unsigned components_specificity_score; } weight;» with lexicographic
comparisons.  The following is equivalent to that —

diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 7d9bf05d6..4868bee7e 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -367,6 +367,7 @@ setstypat(Style s, char *pat, Patprog prog, char **vals, int eval)
 
 	if (*str == ':') {
 	    /* Yet another component. */
+	    weight += (1 << 16);
 
 	    first = 1;
 	    weight += tmp;

— though I'd call it only a proof of concept, since 32767 components in
a zstyle context ought to be enough for anybody :P

This patch breaks the test I posted in 45722, as expected.

Given the feedback so far, though, perhaps I should just commit this
patch?

Cheers,

Daniel
(I suppose we could use «1 << (CHAR_BIT * sizeof(weight) / 2)» to let
people on 64-bit systems use absurdly long zstyle contexts…)



Messages sorted by: Reverse Date, Date, Thread, Author