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

Re: trying to understand how the zsh completer works



I'm wondering if this doesn't belong on zsh-users rather than -workers?

On Feb 28,  6:38pm, joe M wrote:
}
} I am trying to tell the completer to use a different completer based
} on context.
}
} In this situation, I am trying to tell it to use the _approximate
} completer when completing the argument-rest context of grep.

Unfortunately this is one of the things that mostly doesn't work.  The
set of completers is determined very early in the process when the
context is still very non-specific -- because it is the completers
themselves that supply the semantic analysis to fill out the rest of
the context.

Note that the definition of a the zstyle context for completion is

    :completion:FUNCTION:COMPLETER:COMMAND:ARGUMENT:tag

This roughly corresponds to how far down into the completion process
the current operation has progressed.  More detail is appended to the
context at each stage.

The current completer is the third component; by the time the context
has been built up to the fifth component, it's way too late for the
style "completer" to be meaningful.  It can only be usefully looked
up at the very beginning (:completion:) or during the first FUNCTION
(:completion:hist-complete: to use one of your examples).

In retrospect it might have been useful to split the context analysis
from the generation of matches, rather than having a single function
responsible for doing both parts for each command name.  On the other
hand that would have doubled the number of functions (or at least the
number of call signatures) and we'd probably never have gotten done
with the implementation. :-}

If you do put _approximate in the global list of completers, you can
see where it appears in the context -- see how it's "upstream" from
*:grep:argument-rest: ?

tags in context :completion::approximate:::
    corrections original  (_approximate)
tags in context :completion::approximate-1:grep::
    argument-rest options  (_arguments _grep (eval))
tags in context :completion::approximate-1:grep:argument-rest:
    globbed-files  (_files _arguments _grep (eval))
tags in context :completion::approximate-1:grep:options:
    options  (_describe _arguments _grep (eval))
tags in context :completion::complete:grep::
    argument-rest options  (_arguments _grep (eval))
tags in context :completion::complete:grep:argument-rest:
    globbed-files  (_files _arguments _grep (eval))

This means that _approximate is (indirectly) calling _grep, not the
other way around as you might expect.

The only workaround for this is to do your own context analysis and
embed that in the style value via "zstyle -e".  Something like:

zstyle -e ':completion:*' completer \
 'reply=(_complete); \
  (( $CURRENT > 2 )) && [[ $words[1] = grep ]] && reply+=(_approximate)'

Yes, this could get ugly quickly if you want to customize a lot of
completers for individual commands or word positions.



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