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

Re: Questions about completion matchers

On Sun, Oct 10, 2021 at 12:59 AM Oliver Kiddle <opk@xxxxxxx> wrote:
> Marlon Richert wrote:
> > Thanks, Oliver, for your long and thoughtful response. I'm afraid I don't quite
> > understand all of it, though. Let me try to explain how I've understood things,
> > but in a way that I find easier to process, and do please correct me where I'm
> > wrong.
> >
> > The way I've understood it, is that, if $word contains the command line string
> > for which completion is attempted, then each matcher should transform $word as
> > follows:
> That's not what the implementation does in any real sense so I'm not
> sure how helpful it is to reframe the regular expressions I gave in zsh
> syntax. But the effect is along those basic lines if you view the
> "transformed" $word as being a pattern that is matched against each of
> the candidate matches in turn to decide which to present as matches.
> I find it helpful as a brief reference but if it doesn't make sense to
> you, ignore it.

It didn't make sense at first, because I somehow overlooked that you
were using regex. I read them as glob patterns. :)

But now that I realize that, let me have a second look:

On Sun, Sep 26, 2021 at 4:09 PM Oliver Kiddle <opk@xxxxxxx> wrote:
> With matching control, it is often easiest if you view it as converting
> what is on the command-line into a regular expression. I haven't probed
> the source code to get a precise view of how these are mapped. For my
> own purposes, I keep a list but don't trust it in all cases because I've
> found contradictory examples and tweaked it more than once, perhaps
> making it less accurate in the process. So with the caveat that this
> may contain errors, my current list is as follows:
> Not that that starting point is:
>   [cursor position] → .*
> Then:
>   'm:a=b'       – a     → b             (* doesn't work on rhs)
>   'r:|b=*'      – b     → [^b]*b

The appearance of [^a] and [^b] in your patterns was a complete
surprise to me. I would've expected * to work as * in a glob
expression. This is not clear from the docs. Now that I know that the
matcher syntax was based on regex, it makes more sense, but I still
wouldn't have figured this out intuitively. A clearer explanation
about this in the docs would be helpful. Yes, it's mentioned somewhere
in the examples, but it should be explained more clearly earlier on.

>   'r:a|b=*'     – ab    → [^b]*a?b

This one looks incorrect to me as it does not match the example in the
docs. From that example, it appears to me that it is supposed to work
like this:
 'r:a|b=*'     – b    → [^b]*ab

>   'r:a|b=c'     - ab    → cb
>   'l:a|=*'      – a     → [^a]*a
>   'l:a|b=*'     – ab    → [^a]*ab?
Shouldn't these last two result in a[^a]* and ab[^a]*, respectively,
since the anchor goes to the left?

>   'l:a|b=c'     – ab    → ac
>   'b:a=*'       – ^a    → .*

Oh, but here * does work like a * glob? So, I guess * behaves
differently only when anchors are involved?

>   'b:a=c'       – ^a    → ^c
>   'e:a=*'       – a$    → .*
>   'r:a||b=*'    – b     → [^a]*ab       (only * works on rhs, empty a or b has no use)
>   'l:a||b=*'    – ^a    → a.*           (only * on rhs, empty a no use, b ignored?!)

The comments on the last two items sound like bugs to me. Also,
'l:a||b=*' should work on just 'a' and not require '^a'.

On Sun, Oct 10, 2021 at 12:59 AM Oliver Kiddle <opk@xxxxxxx> wrote:
> The difference between b: and l: with an empty anchor (or e/r) is not
> encapsulated by my regular expressions. They only differ in how strict
> the anchoring to the start of the match is where another matching
> control allowed extra characters to be inserted at the beginning.

So, does that mean then that matcher are not evaluated strictly left-to-right?

> The example given when this was added was zsh option completion where
> underscores are ignored and a prefix of NO is allowed.

About that example, what exactly is the difference between L: and B:
that lets B: complete '_NO_f' to '_NO_foo' and 'NONO_f' to 'NONO_f'
but not L:? It's not clear from the example, let alone from the
description of the matchers.

> I took a look at the source code and dug out original -workers posts and
> it does seem that the intention for the two anchor || forms was as I
> thought. Even as designed I don't think either is ideal for camel case -
> the l: form excludes characters from the wrong anchor for that.
> The matching code looks a lot like regular expression matching with a
> back tracking algorithm.

Y02compmatch.ztst contains a lot of examples that could be added to
the docs to better explain how the different matchers are intended to
be used. It would help to better understand their workings.

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