zsh-workers
 help / color / mirror / code / Atom feed
From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@sunsite.auc.dk
Subject: Functions for multiple commands
Date: Fri, 6 Oct 2000 09:18:05 +0200 (MET DST)	[thread overview]
Message-ID: <200010060718.JAA14463@beta.informatik.hu-berlin.de> (raw)


I thought of several ways to restructure these completion functions for
multiple commands/contexts. Below are those I liked best.

In the following, I'll call such functions `digests'. Never mind.
`collections' might be a better name.

1)
Each command/context has its own function. The autoloaded function
only defines those functions (and may contain other initialisation
code, like defining cache-arrays or whatever).

For such files, we use a new tag, say `#digest'. The tag lines contain
the mappings from command/context to sub-functions, e.g. as in:

  #digest cmd1:sub-func1 cmd2:sub-func2 ...

Then there are three possibilities:

a)
The code that handles `#digest' tags immediately calls them, during
compinit. That allows other functions to call the sub-functions directly
and $_comp only needs to contain the name of the sub-function, i.e.
users can just do:

  compdef sub-func cmd ...

And as long as they are easy to see in the file (or documented)...

But of course having to call the functions during initialisation is ugly.

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 ...'.

In this case we have to change the code that invokes completion functions.
We could of course add a helper function for that, which gets the name
of the command/context as argument:

  foo() {
    local func digest
    func="$_comp[$1]"
    digest="${(k)_digest[(R)* $func *]}"
    if [[ -n "$digest" ]]; then
      "$digest"
      unfunction "$digest"
      unset "_digest[$digest]"
    fi
    "$func"
  }

I'm not exactly sure how big a problem it is that this means that sub-
functions are not directly callable.

c)
That could be avoided with a bit of magic, namely: the function handling
`#digest' creates dummy-functions for the sub-functions, like this:

  # name of sub-function is in $sub, name of digest function is in $digest
  (( $+functions[$sub] )) ||
    functions[$sub]="
      if (( \$+functions[$digest] )); then
        $digest
        unfunction $digest
      fi
      $sub"

Without mapped .zwc files, this might be faster (and certainly more memory-
saving than 1a)). But still...

And in any case, digest-file writers would have to use:

  (( $+functions[_foo] )) || _foo() { ... }

so that sub-functions found earlier (in user-defined autoloaded files)
override those found later.

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 and
the `#digest' line contains the mappings from commands/contexts to
`services'. The function handling `#digest' saves those mappings in an
associative array, say $_digest. Again, we need special code to call
the function:

  func="$_comp[$cmd]"
  if (( $+_digest[$func] )); then
    "$_digest[$func]" "$func"
  else
    "$func"
  fi

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.

2b)
And of course, we could also combine this with 1c) and define dummy
functions for the `services' that just call the autoloaded function with
the argument. Together with 2a) we could also add a second syntax to
define `services' for which functions should be created (next to those
for which no functions are created).


Currently, I'm not sure which I like best. Comments? Opinions? Other
possibilities?


Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


             reply	other threads:[~2000-10-06  7:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-10-06  7:18 Sven Wischnowsky [this message]
2000-10-08 17:34 ` Bart Schaefer
2000-10-09 11:23 Sven Wischnowsky

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=200010060718.JAA14463@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).