From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@sunsite.auc.dk
Subject: Re: Functions for multiple commands
Date: Mon, 9 Oct 2000 13:23:45 +0200 (MET DST) [thread overview]
Message-ID: <200010091123.NAA18212@beta.informatik.hu-berlin.de> (raw)
In-Reply-To: "Bart Schaefer"'s message of Sun, 8 Oct 2000 17:34:47 +0000
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@informatik.hu-berlin.de
next reply other threads:[~2000-10-09 11:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-10-09 11:23 Sven Wischnowsky [this message]
-- strict thread matches above, loose matches on Subject: below --
2000-10-06 7:18 Sven Wischnowsky
2000-10-08 17:34 ` Bart Schaefer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200010091123.NAA18212@beta.informatik.hu-berlin.de \
--to=wischnow@informatik.hu-berlin.de \
--cc=zsh-workers@sunsite.auc.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).