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

Re: still confused about completion and matching

You may find messages about completion on patterns, including **/ in
the archive (sorry, can't remember the message numbers, maybe Adam or
Andrej can help). One thing I can remember us saying about the **
thing is that this might, urgh, be terribly slow in some cases.

I'll first try to clarify some things and then comment on some of your 
remarks (I guess you already figured out most of the following).

The most important thing you have to know about completion and
matching is that here are two ways to do it. You get the `normal' one
with glob_complete unset, which is the same as
compstate[pattern_match] unset or empty. In this case the completion
system only uses the prefix and suffix from the line and the match
specs (set with the matcher-list and matcher styles, given to the -M
option of compadd).

The other way is selected with compstate[pattern_match] set to a
non-empty string. In that case the string from the line is taken as a
pattern and compared to the possible completions. BUT without the
prefixes and suffixes given with the -[psiI] options to compadd. In
filename completion, these are the path-prefixes and -suffixes. They
are still matched `normally'. And it has to be this way because the
completion code (the C-code) has to be able to build a common string
for them which it can if they differ only as far as match specs allow, 
but it can't do that for arbitrary strings matched by a pattern.
Also, since patterns allow for completely different matches, menu
completion is normally started. After all, the user started
`completion', not `listing'. The pattern_insert key of compstate is
expected to be only seldom of any use.

That leaves only the possibility to move the suffixes into the words
given to compadd. This would be done in lines 488-510 in _path_files.
That together with using a non-empty value for compstate[pattern_match]
should bring you nearer to what you want. But note that this won't be
added to _path_files if it is done unconditionally. Seeing only the
ambiguous component is much clearer for most cases.

Some remarks:

> if I type
> zsh% ls u?/q/_TAB
> I get menu completion with the choices /u1, /u2, and /u4 and with my
> command line cycling through u1/q/, u2/q/, and /u4/q/, each time I hit
> TAB.  If when it says u2/q/ I hit space, backspace, TAB, then u2/q/
> becomes u2/q1/e2/.  It is as if the completion system is imagining a *
> after the q and before the /.  I thought this would happen only if I
> had compstate[pattern_match]='*', not ='-'.  Am I confused?

The whole point of _path_files is to do exactly that. Completing
multiple pathname components at once. And, as explained above, this
has *nothing* to do with compstate[pattern_match].

> As I was researching all this, I was looking at _match to see whether
> I could get that to do what I wanted.  I am very confused about line
> 47:
>    $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 

compstate[unambiguous] is the unambiguous string the completion code
was able to build for all matches added. The test just checks if that
string is longer than the original string (which is split at the
cursor position into $PREFIX and $SUFFIX). You have the feeling that
this is a hack, you are right. It was my first and, until now, last
attempt to come up with a sensible condition for deciding if an
unambiguous string may make sense. That's all.

So... there are two completely different things one could do. First,
using only strings without patterns (all your exampleds except the **
thing used only a ? at the end, given the same as an * at the end,
which is normal for _path_files anyway). One could then add a style to 
control if the whole ambiguous suffixes should be shown in the
list. Another style could be used to say that the cursor should stay
where it is if there are ambiguities both at the end and in a previous 
component. For both styles there might be other things one could
reasonably make them conditional upon, but I think only experience
could show what they are.

Or one could try to add this multi-component pattern behaviour. One
would need to add code that decides if for a certain component the
original string or the one generated should be used. The original
string would keep the pattern unchanged, of course. This is already
not trivial to decide because only later components say if a previous
one should be left alone or not. Then, when the prefix is unambiguous, 
i.e. if one or more components should be replaced with the only matching
directory names, there are two possibilities. First, one could use the
-U option of compadd (although I would generally not suggest to ever
use -U, at least not in a normal completion context). Or one could
trick the completion code into believing that everything is fine by
setting PREFIX and SUFFIX to the string(s) that are inserted. That
would make it use matching, but since the strings are the same... As
far as can think, this should even make it possible to modify the
prefix and list possible matches for a later component (listing them
without the unambiguous prefix) at the same time (on the same
completion attempt). In other words, this might allow you to do what
you wanted.


Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx

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