Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Functions for multiple commands
- X-seq: zsh-workers 12928
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: Re: Functions for multiple commands
- Date: Mon, 9 Oct 2000 13:23:45 +0200 (MET DST)
- In-reply-to: "Bart Schaefer"'s message of Sun, 8 Oct 2000 17:34:47 +0000
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
Bart Schaefer wrote:
> On Oct 6, 9:18am, Sven Wischnowsky wrote:
> }
> } I thought of several ways to restructure these completion functions for
> } multiple commands/contexts. Below are those I liked best.
>
> You've probably run off to play with this over the weekend and I'm too
> late to give much useful feedback, but:
No, I got a surprise visit and had almost not time at the weekend...
> ...
>
> } b)
> } One way to avoid that: the function that handles `#digest' only saves the
> } mappings from the autoloaded function to the sub-functions in an
> } associative array, say $_digest. Keys are the autoloaded functions, values
> } are formed like ' sub-func1 sub-func2 ...'.
>
> What other interesting thing do you envisage doing with the autoloaded
> function names that they need to be the keys? Just unset the elements?
Yes, I was thinking only about the unset... (and, yes, before I was
thinking about using the names of the sub-funcs be the keys).
> ...
>
> Er, I don't like that `unfunction $digest' in there: It means that the
> name of the digest can't be the name of one of the sub-functions (e.g.,
> the way _rlogin is in the patch I sent). Let the digest function do its
> own unfunctioning, if that's appropriate.
Yes.
> } I'm not exactly sure how big a problem it is that this means that sub-
> } functions are not directly callable.
>
> How often is any completion-system function meant to be directly called?
Well, we have these helper functions like _pids and _diff_options. But
of course, if someone writes such a collection-in-one-file he could
always put interesting sub-functions into their own files.
> } c)
> } That could be avoided with a bit of magic, namely: the function handling
> } `#digest' creates dummy-functions for the sub-functions [...]
> } And in any case, digest-file writers would have to use:
> }
> } (( $+functions[_foo] )) || _foo() { ... }
>
> The dummy function must then unfunction *itself* before calling the
> digest function, or none of the real sub-functions will ever become
> defined!
Right.
> However:
>
> } so that sub-functions found earlier (in user-defined autoloaded files)
> } override those found later.
>
> I disagree with this (and it's use in _cvs continually annoys me, BTW,
> because it makes it difficult to load a revised version into a running
> shell). Either those functions are all intended to be used together,
> or they are not; if so, I want them all defined, and if not, they should
> not all be contained in the same source file.
>
> Rather than testing $+functions[...], I'd prefer to test $_comps[...]
> in the way that was done in the _rlogin patch I sent. If the user wants
> to override a completion function with his own autoloads, he should also
> explicitly compdef for that function. (This of course doesn't apply to
> helper functions that are designed to be replaced, only to completion
> "callbacks" themselves.)
Hmhm. Right again.
> } 2)
> } Using only one autoloaded function, no sub-functions. The function then
> } uses a big `case', the `service' to use is given as the first argument
>
> Returning to Jay's original example (using _rlogin for krsh et al.), how
> is this idea qualitatively different from writing a little wrapper that
> looks like:
>
> #compdef krsh krcp
> words[1]=$words[1]:s/k//
> _rlogin
One doesn't need to write a wrapper fuction, one only does
compdef _rsh krsh
compdef _rcp krcp
> } 2a)
> } Instead of `#digest', we could also use `#compdef' and allow a special
> } syntax to mean that for a certain command/context the autoloaded function
> } should be called with a `service'-argument.
>
> Aside: Using new compdef syntax instead of #digest would work with idea #1.
Of course.
> Let me ramble a little on this particular idea. (As if I haven't already
> been.) Instead of an _digest assoc, we'd have an _services assoc. Then
> we'd change calls to the function in $_comps[$words[1]] to also pass as
> an argument $_services[$words[1]]. The #compdef line could look like:
>
> #compdef -s rlogin=rlogin rsh=rsh remsh=rsh rcp=rcp
> The LHS of the = is the key into _comps and _services, the RHS
> is the value for that key in _services
> or
> #compdef -S rlogin rsh remsh rcp
> Shorthand for rlogin=rlogin rsh=rsh remsh=remsh rcp=rcp
>
> So the result (in the first case) would be that _comps[remsh]=_rlogin
> and _services[remsh]=rsh, and so on.
>
> The nice thing about this is that we don't need any special magic when
> the function is called. _normal always passes $_services[$words[1]]
> when it exists. Also, the meaning of the service is entirely up to the
> called function; the completion system isn't forced to interpret it as
> a function name.
>
> I'm leaning heavily towards this approach, at the moment.
Hmhm, agreed. Actually, I was mostly concerned with getting tarred and
feathered when suggesting yet another level of indirection, which this
is, even though that extra level isn't used in most functions.
> ...
>
> For example, suppose we choose (2a). Then _rlogin could look something
> like:
>
> #compdef -S rlogin rcp rsh remsh
>
> _rsh() {
> # guts of rsh service ...
> }
> _rcp() { ... }
> _rsh() { ... }
>
> case $1 in
> remsh) 1=rsh ;&
> rsh|rcp)
> _comps[$words[1]]=_$1
> unset _services[$words[1]] # this is not even strictly necessary
> _$1 ;;
> *)
> # guts of rlogin service ...
> ;;
> esac
>
> Thus turning (2a) into (1b). I'm not sure what the ramifications of this
> sort of thing would be for efficiency of .zwc file loading.
Defining functions is cheap when using mapped .zwc files. Still, one
could change the above so that _rlogin re-defines itself with a
function containing only the `case...'. That would make it even
faster (and then we probably don't even need to modify $_comps).
We could even add a utility function (_dispatch or some such) that
implements the `case...' in a generic way.
So, is anyone against adding support for such `services'? Is that name
acceptable?
Bye
Sven
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author