* multiple-commands-functions
@ 2000-10-11 7:32 Sven Wischnowsky
2000-10-11 14:46 ` multiple-commands-functions Bart Schaefer
0 siblings, 1 reply; 4+ messages in thread
From: Sven Wischnowsky @ 2000-10-11 7:32 UTC (permalink / raw)
To: zsh-workers
[I've prepared some patches yesterday, I'm not sure about any of them,
so I'll just post them for further discussion, without committing them.]
We were discussing ways to improve functions like _rlogin. The
original request could be reduced to something like: is there a way to
make it easier to use one of the `services' of such functions?
Then Bart and I more-or-less suggested to use those `services' as an
abstraction so that functions could use `#compdef rsh remsh=rsh...'.
The service name would then be given as an argument to the function
and it could decide what to do with it.
But that has an ugly side-effect: some of the functions already use
the arguments, for options. For example, _pbm can be used as a
top-level function and also calls itself to complete only appropriate
files. Another problem of some of the solutions suggested is that they
modify $_comps which may make re-loading impossible.
That made me think about ways to simplify it, or to report the service
somewhere else, in a (completion-system-)global parameter. From there
it was only a small step to the patch below. It allows to define
`completion aliases' (there it is again, `aliases' -- well, we could
change that name, of course). For example, in an autoloaded function,
`#compdef rsh remsh=rsh' defines the alias `remsh=rsh'. The code
calling completion functions checks if $words[1] is equal to `remsh'
and if it is, it will call the completion function for `rsh', but
before that, it sets $words[1] to `rsh'. I.e. the function only has to
check for $words[1] = rsh. Put the other way, `rsh' is the `service'.
It is also possible to define completion aliases directly with
compdef, with the new option -A: `compdef -A krsh=rsh ...' says that
completion for `krsh' should be done as for `rsh'. I like this,
because it is independent of the function (and sub-function or
case-branch) used for `rsh' -- users don't have to worry about that.
The only thing we would have to worry about is functions that call the
command we are completing for. Since this is needed less often than
finding the `service', it would probably make sense to put the
original command name into a (completion-system-)global parameter and
use that everywhere we need to call the command. I haven't implemented
that yet, though.
Bye
Sven
diff -u -r ../oz/Completion/Core/_compalso ./Completion/Core/_compalso
--- ../oz/Completion/Core/_compalso Tue Oct 10 19:36:47 2000
+++ ./Completion/Core/_compalso Tue Oct 10 20:09:55 2000
@@ -10,6 +10,7 @@
local i tmp ret=1
for i; do
+ (( $+_compaliases[$1] )) && 1="$_compaliases[$1]"
tmp="$_comps[$1]"
[[ -z "$tmp" ]] || "$tmp" && ret=0
done
diff -u -r ../oz/Completion/Core/_normal ./Completion/Core/_normal
--- ../oz/Completion/Core/_normal Tue Oct 10 19:36:47 2000
+++ ./Completion/Core/_normal Tue Oct 10 20:06:50 2000
@@ -15,6 +15,11 @@
# a path and the last path name component).
command="$words[1]"
+if (( $+_compaliases[$command] )); then
+ command="$_compaliases[$command]"
+ words[1]="$command"
+fi
+
if [[ CURRENT -eq 1 ]]; then
curcontext="${curcontext%:*:*}:-command-:"
diff -u -r ../oz/Completion/Core/compdump ./Completion/Core/compdump
--- ../oz/Completion/Core/compdump Tue Oct 10 19:36:47 2000
+++ ./Completion/Core/compdump Tue Oct 10 20:21:45 2000
@@ -35,12 +35,18 @@
print "#files: $#_d_files" > $_d_file
-# First dump the arrays _comps and _patcomps. The quoting hieroglyphyics
-# ensure that a single quote inside a variable is itself correctly quoted.
+# First dump the arrays. The quoting hieroglyphyics ensure that a single
+# quote inside a variable is itself correctly quoted.
print "_comps=(" >> $_d_file
for _d_f in ${(ok)_comps}; do
print -r - "${(q)_d_f}" "${(q)_comps[$_d_f]}"
+done >> $_d_file
+print ")" >> $_d_file
+
+print "_compaliases=(" >> $_d_file
+for _d_f in ${(ok)_compaliases}; do
+ print -r - "${(q)_d_f}" "${(q)_compaliases[$_d_f]}"
done >> $_d_file
print ")" >> $_d_file
diff -u -r ../oz/Completion/Core/compinit ./Completion/Core/compinit
--- ../oz/Completion/Core/compinit Tue Oct 10 19:36:47 2000
+++ ./Completion/Core/compinit Tue Oct 10 20:43:37 2000
@@ -100,12 +100,13 @@
esac
done
-# The associative array containing the definitions for the commands.
+# The associative arrays containing the definitions for the commands and
+# the completion aliases.
# Definitions for patterns will be stored in the associations `_patcomps'
# and `_postpatcomps'. `_compautos' contains the names and options
# for autoloaded functions that get options.
-typeset -gA _comps _patcomps _postpatcomps _compautos
+typeset -gA _comps _compaliases _patcomps _postpatcomps _compautos
# The associative array use to report information about the last
# cmpletion to the outside.
@@ -181,16 +182,16 @@
# delete the definitions for the command names `bar' and `baz'
compdef() {
- local opt autol type func delete new i
+ local opt autol type func delete new i ali
# Get the options.
- if [[ $#* -eq 0 ]]; then
- echo "compdef needs parameters"
+ if (( ! $# )); then
+ echo "#0: I need arguments"
return 1
fi
- while getopts "anpPkKd" opt; do
+ while getopts "anpPkKdA" opt; do
case "$opt" in
a) autol=yes;;
n) new=yes;;
@@ -211,16 +212,44 @@
fi
;;
d) delete=yes;;
+ A) ali=yes;;
esac
done
shift OPTIND-1
- if [[ $#* -eq 0 ]]; then
- echo "compdef needs parameters"
+ if (( ! $# )); then
+ echo "$0: I need arguments"
return 1
fi
-
- if [[ -z "$delete" ]]; then
+
+ if [[ -n "$ali" ]]; then
+ if [[ -n "$autol$type" ]]; then
+ echo "$0: -A can't be combined with other options"
+ return 1
+ fi
+ if [[ -z "$delete" ]]; then
+ ali=0
+ for i; do
+ if [[ "$i" != *\=* ]]; then
+ echo "$0: invalid argument: \`$i'"
+ ali=1
+ else
+ new="${i#*\=}"
+ if (( $+_compaliases[$new] )); then
+ _compaliases[${i%%\=*}]="$_compaliases[$new]"
+ _comps[${i%%\=*}]="$_comps[$_compaliases[$new]]"
+ else
+ _compaliases[${i%%\=*}]="$new"
+ _comps[${i%%\=*}]="$_comps[$new]"
+ fi
+ fi
+ done
+ return ali
+ else
+ unset _compaliases\[${^*}\]
+ return
+ fi
+ elif [[ -z "$delete" ]]; then
# Adding definitions, first get the name of the function name
# and probably do autoloading.
@@ -290,15 +319,15 @@
*)
# For commands store the function name in the `_comps'
# associative array, command names as keys.
- if [[ -z "$new" ]]; then
- for i; do
- _comps[$i]="$func"
- done
- else
- for i; do
- [[ "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func"
- done
- fi
+
+ for i; do
+ if [[ "$i" = *\=* ]]; then
+ _compaliases[${i%%\=*}]="${i#*\=}"
+ _comps[${i%%\=*}]="$_comps[${i#*\=}]"
+ else
+ [[ -z "$new" || "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func"
+ fi
+ done
;;
esac
else
diff -u -r ../oz/Completion/User/_rlogin ./Completion/User/_rlogin
--- ../oz/Completion/User/_rlogin Tue Oct 10 19:36:48 2000
+++ ./Completion/User/_rlogin Tue Oct 10 20:38:28 2000
@@ -1,4 +1,4 @@
-#compdef rlogin rsh remsh rcp
+#compdef rlogin rsh remsh=rsh rcp
_rlogin () {
case "${words[1]:t}" in
@@ -9,7 +9,7 @@
'-l[specify login user name]:login as:_rlogin_users' \
':remote host name:_rlogin_hosts'
;;
- rsh|remsh)
+ rsh)
local context state line ret=1
typeset -A opt_args
diff -u -r ../oz/Completion/User/_ssh ./Completion/User/_ssh
--- ../oz/Completion/User/_ssh Tue Oct 10 19:36:48 2000
+++ ./Completion/User/_ssh Tue Oct 10 20:20:28 2000
@@ -1,4 +1,4 @@
-#compdef ssh slogin scp ssh-add ssh-agent ssh-keygen
+#compdef ssh slogin=ssh scp ssh-add ssh-agent ssh-keygen
_remote_files () {
local expl files
@@ -18,7 +18,7 @@
# ssh-opt is a pseudo-command used to complete ssh options for `scp -o'.
case "${words[1]:t}" in
- ssh|slogin)
+ ssh)
args=(
':remote host name:->userhost'
'(-):command: _command_names -e'
diff -u -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo
--- ../oz/Doc/Zsh/compsys.yo Tue Oct 10 19:36:41 2000
+++ ./Doc/Zsh/compsys.yo Tue Oct 10 21:11:20 2000
@@ -164,6 +164,10 @@
either the name of a command whose arguments are to be completed or one of
a number of special contexts in the form tt(-)var(context)tt(-) described
below for the tt(_complete) function.
+
+Each var(name) may also be of the form `var(name1)tt(=)var(name2)'.
+This makes the function be used to complete arguments for var(name1)
+and ensures that the function treats it as if completing for var(name2).
)
item(tt(#compdef -p) var(pattern))(
The file will be made autoloadable and the function defined in it will be
@@ -250,7 +254,8 @@
xitem(tt(compdef -p) [ tt(-a) ] var(function pattern))
xitem(tt(compdef -P) [ tt(-a) ] var(function pattern))
xitem(tt(compdef -k) [ tt(-an) ] var(function style key-sequences...))
-item(tt(compdef -K) [ tt(-an) ] var(function name style key-sequences ...))(
+xitem(tt(compdef -K) [ tt(-an) ] var(function name style key-sequences...))
+item(tt(compdef -A) var(aliases...))(
The first form tells the completion system to call the given
var(function) when completing for the contexts or commands
whose var(names) are given: this is like the tt(#compdef) tag. If the
@@ -285,6 +290,11 @@
for tt(-k) and the first must be a unique widget name beginning with an
underscore.
+The form with tt(-A) defines the completion var(aliases), each of
+which has to be of the form `var(command1)tt(=)var(command2)'. Such an
+alias makes the arguments of var(command1) be completed in the same
+way as those for var(command2).
+
In each of the forms supporting it the tt(-a) option makes the
var(function) autoloadable (exactly equivalent to
tt(autoload -U )var(function)).
@@ -301,7 +311,15 @@
example(compdef _pids foo)
using the tt(_pids) function from the distribution to generate the
-process identifiers. Not also the tt(_use_lo) function described
+process identifiers. Completion aliases are intended to express that
+completion for a command has to be done in the same way as for another
+command, e.g.:
+
+example(compdef -A foo=rsh)
+
+says that completion for tt(foo) has to be done as for tt(rsh).
+
+Note also the tt(_use_lo) function described
below, which can be used to complete options for commands that
understand the `tt(-)tt(-help)' option.
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: multiple-commands-functions
2000-10-11 7:32 multiple-commands-functions Sven Wischnowsky
@ 2000-10-11 14:46 ` Bart Schaefer
0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2000-10-11 14:46 UTC (permalink / raw)
To: Sven Wischnowsky, zsh-workers
On Oct 11, 9:32am, Sven Wischnowsky wrote:
}
} Then Bart and I more-or-less suggested to use those `services' as an
} abstraction so that functions could use `#compdef rsh remsh=rsh...'.
} The service name would then be given as an argument to the function
} and it could decide what to do with it.
}
} But that has an ugly side-effect: some of the functions already use
} the arguments, for options.
Hrm. That's easily fixable, though. E.g. in _pbm, you'd just have to add
an extra argument as $1 when making the recursive call, to identify it as
"the recursive call service".
But it would be just as easy to put the service name in a non-positional.
} Another problem of some of the solutions suggested is that they
} modify $_comps which may make re-loading impossible.
That was only necessary to implement one of the suggestions in terms of
the other one, but nevertheless ...
} That made me think about ways to simplify it, or to report the service
} somewhere else, in a (completion-system-)global parameter. From there
} it was only a small step to the patch below. It allows to define
} `completion aliases' (there it is again, `aliases' -- well, we could
} change that name, of course). For example, in an autoloaded function,
} `#compdef rsh remsh=rsh' defines the alias `remsh=rsh'. The code
} calling completion functions checks if $words[1] is equal to `remsh'
} and if it is, it will call the completion function for `rsh', but
} before that, it sets $words[1] to `rsh'. I.e. the function only has to
} check for $words[1] = rsh. Put the other way, `rsh' is the `service'.
Hmm. What happens if the completion is attempted like:
zsh% /usr/local/bin/krsh <TAB>
?? It doesn't look as though that will work properly.
Are there any other cases where the format of $words[1] could mess up a
simple aliasing scheme? The advantage of the previous proposals was
that they changed the call to the completion function, not the way it
was looked up, so there wasn't any chance for this kind of confusion.
If we do go with this sort of aliasing, one other thing I'd suggest is
that it be possible to combine this with -p so that the left-hand-side
could be a pattern, e.g.
compadd -p -A '*r(em|)sh=rsh'
but perhaps that's not useful enough to be worth the effort.
} The only thing we would have to worry about is functions that call the
} command we are completing for. Since this is needed less often than
} finding the `service', it would probably make sense to put the
} original command name into a (completion-system-)global parameter and
} use that everywhere we need to call the command.
In spite of the "needed less often" argument, I'd still recommend putting
the service in a different parameter and leaving $words alone. If the
positionals won't work, then invent another parameter (local to _normal
but "global" to the called functions) to store the service. Most of the
time there'll be a one-to-one mapping between functions and services and
neither the service parameter nor $words[1] will be looked at.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: multiple-commands-functions
@ 2000-10-11 14:56 Sven Wischnowsky
0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-10-11 14:56 UTC (permalink / raw)
To: zsh-workers
Bart Schaefer wrote:
> On Oct 11, 9:32am, Sven Wischnowsky wrote:
> }
> } Then Bart and I more-or-less suggested to use those `services' as an
> } abstraction so that functions could use `#compdef rsh remsh=rsh...'.
> } The service name would then be given as an argument to the function
> } and it could decide what to do with it.
> }
> } But that has an ugly side-effect: some of the functions already use
> } the arguments, for options.
>
> Hrm. That's easily fixable, though. E.g. in _pbm, you'd just have to add
> an extra argument as $1 when making the recursive call, to identify it as
> "the recursive call service".
And then one would have to remember that the utility functions don't
need that, but the multi-functions-used-as-utilities do.
> ...
>
> } That made me think about ways to simplify it, or to report the service
> } somewhere else, in a (completion-system-)global parameter. From there
> } it was only a small step to the patch below. It allows to define
> } `completion aliases' (there it is again, `aliases' -- well, we could
> } change that name, of course). For example, in an autoloaded function,
> } `#compdef rsh remsh=rsh' defines the alias `remsh=rsh'. The code
> } calling completion functions checks if $words[1] is equal to `remsh'
> } and if it is, it will call the completion function for `rsh', but
> } before that, it sets $words[1] to `rsh'. I.e. the function only has to
> } check for $words[1] = rsh. Put the other way, `rsh' is the `service'.
>
> Hmm. What happens if the completion is attempted like:
>
> zsh% /usr/local/bin/krsh <TAB>
>
> ?? It doesn't look as though that will work properly.
I only remembered that after I sent it (but have put it into my list
as a if-..-then). It could be solved by changing how _normal looks up
these aliases.
> Are there any other cases where the format of $words[1] could mess up a
> simple aliasing scheme? The advantage of the previous proposals was
> that they changed the call to the completion function, not the way it
> was looked up, so there wasn't any chance for this kind of confusion.
Hm, ... I was mostly wondering if changing $words[1] could affect
other places that is used.
> If we do go with this sort of aliasing, one other thing I'd suggest is
> that it be possible to combine this with -p so that the left-hand-side
> could be a pattern, e.g.
>
> compadd -p -A '*r(em|)sh=rsh'
>
> but perhaps that's not useful enough to be worth the effort.
Dunno, easy to implement, though.
> } The only thing we would have to worry about is functions that call the
> } command we are completing for. Since this is needed less often than
> } finding the `service', it would probably make sense to put the
> } original command name into a (completion-system-)global parameter and
> } use that everywhere we need to call the command.
>
> In spite of the "needed less often" argument, I'd still recommend putting
> the service in a different parameter and leaving $words alone. If the
> positionals won't work, then invent another parameter (local to _normal
> but "global" to the called functions) to store the service. Most of the
> time there'll be a one-to-one mapping between functions and services and
> neither the service parameter nor $words[1] will be looked at.
Yes, that's the other way I was thinking about, too...
Bye
Sven
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: multiple-commands-functions
@ 2000-10-12 9:12 Sven Wischnowsky
0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-10-12 9:12 UTC (permalink / raw)
To: zsh-workers
I think Bart will like this one better. And I probably do, too.
What I was really only after was to avoid that argument-thing we
discussed and to make live for the users easier, so that they don't
have to care about which function provides a known service.
So this patch uses the completion-system-global parameter $service to
report the service to use to the completion functions. These functions
should then almost always use that instead of $words[1]. Definition of
services is still done with `#compdef foo bar=foo'. But there is an
extra bit of cleverness in compdef. If the first argument is of the
form `cmd=service', i.e. it does not name a function, this really
defines what I called completion aliases in my last attempt (I haven't
called them like that this time). This works by making compdef find
out which function implements the service and making that function
(with that service) be used when completing for command `cmd'. Since
in most cases `services' will really only be commands, one can do:
compdef krsh=rsh ...
to say that arguments for krsh should be completed as for rsh. One
doesn't need to know that it's _rlogin that implements the service
`rsh'. But of course:
compdef _rlogin krsh=rsh
works, too.
I hope everyone agrees that this shortcut is interesting to have.
Most of the patch changes completion functions to use $service instead
of $words[1]. Before committing this we'll probably have to go through
it once more to see if there are places where external commands are
invoked that should use $service instead of $words[1] (probably
testing if there is a function/builtin/command named $service).
And before I forget, I'll put it down here: that compadd in
_remote_files() in _ssh should use _wanted.
Bye
Sven
diff -u -r ../oz/Completion/Bsd/_bsd_pkg ./Completion/Bsd/_bsd_pkg
--- ../oz/Completion/Bsd/_bsd_pkg Wed Oct 11 16:23:18 2000
+++ ./Completion/Bsd/_bsd_pkg Wed Oct 11 21:54:41 2000
@@ -13,7 +13,7 @@
}
_bsd_pkg() {
- case "${words[1]:t}" in
+ case "$service" in
pkg_add)
_arguments -s \
'-v[be verbose]' \
diff -u -r ../oz/Completion/Bsd/_kld ./Completion/Bsd/_kld
--- ../oz/Completion/Bsd/_kld Wed Oct 11 16:23:18 2000
+++ ./Completion/Bsd/_kld Wed Oct 11 21:56:48 2000
@@ -21,7 +21,7 @@
}
_kld() {
- case "${words[1]:t}" in
+ case "$service" in
kldload)
_arguments -s \
'-v[be verbose]' \
diff -u -r ../oz/Completion/Core/_compalso ./Completion/Core/_compalso
--- ../oz/Completion/Core/_compalso Wed Oct 11 16:23:14 2000
+++ ./Completion/Core/_compalso Wed Oct 11 21:47:04 2000
@@ -7,11 +7,11 @@
# `_compalso -math-' to get the completions that would be generated for a
# mathematical context.
-local i tmp ret=1
+local i tmp ret=1 service
for i; do
- tmp="$_comps[$1]"
- [[ -z "$tmp" ]] || "$tmp" && ret=0
+ tmp="$_comps[$i]"
+ [[ -z "$tmp" ]] || service="${_services[$i]:-$i}" && "$tmp" && ret=0
done
return ret
diff -u -r ../oz/Completion/Core/_complete ./Completion/Core/_complete
--- ../oz/Completion/Core/_complete Wed Oct 11 16:23:14 2000
+++ ./Completion/Core/_complete Wed Oct 11 21:42:14 2000
@@ -4,7 +4,7 @@
# a normal completion function, but as one possible value for the
# completer style.
-local comp name oldcontext ret=1
+local comp name oldcontext ret=1 service
typeset -T curcontext="$curcontext" ccarray
oldcontext="$curcontext"
@@ -95,6 +95,7 @@
comp="$_comps[-first-]"
if [[ ! -z "$comp" ]]; then
+ service="${_services[-first-]:--first-}"
ccarray[3]=-first-
"$comp" && ret=0
if [[ "$_compskip" = all ]]; then
@@ -123,6 +124,7 @@
ccarray[3]="$cname"
comp="$_comps[$cname]"
+ service="${_services[$cname]:-$cname}"
# If not, we use default completion, if any.
@@ -133,7 +135,8 @@
fi
comp="$_comps[-default-]"
fi
- [[ -z "$comp" ]] || "$comp" && ret=0
+ [[ -z "$comp" ]] ||
+ service="${_services[-default-]:--default-}" && "$comp" && ret=0
fi
_compskip=
diff -u -r ../oz/Completion/Core/_normal ./Completion/Core/_normal
--- ../oz/Completion/Core/_normal Wed Oct 11 16:23:15 2000
+++ ./Completion/Core/_normal Wed Oct 11 21:39:56 2000
@@ -1,7 +1,7 @@
#compdef -command-line-
local comp command cmd1 cmd2 pat val name i ret=1 _compskip="$_compskip"
-local curcontext="$curcontext"
+local curcontext="$curcontext" service
# If we get the option `-s', we don't reset `_compskip'. This ensures
# that a value set in the function for the `-first-' context is kept,
@@ -44,6 +44,7 @@
# See if there are any matching pattern completions.
if [[ "$_compskip" != (all|*patterns*) ]]; then
+ service="${_services[$cmd1]:-$cmd1}"
for i in "${(@)_patcomps[(K)$cmd1]}"; do
"$i" && ret=0
if [[ "$_compskip" = *patterns* ]]; then
@@ -54,6 +55,7 @@
fi
done
if [[ -n "$cmd2" ]]; then
+ service="${_services[$cmd2]:-$cmd2}"
for i in "${(@)_patcomps[(K)$cmd2]}"; do
"$i" && ret=0
if [[ "$_compskip" = *patterns* ]]; then
@@ -71,8 +73,10 @@
ret=1
name="$cmd1"
comp="$_comps[$cmd1]"
+service="${_services[$cmd1]:-$cmd1}"
-[[ -z "$comp" ]] && name="$cmd2" comp="$_comps[$cmd2]"
+[[ -z "$comp" ]] &&
+ name="$cmd2" comp="$_comps[$cmd2]" service="${_services[$cmd2]:-$cmd2}"
# And generate the matches, probably using default completion.
@@ -86,6 +90,7 @@
fi
if [[ "$_compskip" != (all|*patterns*) ]]; then
+ service="${_services[$cmd1]:-$cmd1}"
for i in "${(@)_postpatcomps[(K)$cmd1]}"; do
_compskip=default
"$i" && ret=0
@@ -97,6 +102,7 @@
fi
done
if [[ -n "$cmd2" ]]; then
+ service="${_services[$cmd2]:-$cmd2}"
for i in "${(@)_postpatcomps[(K)$cmd2]}"; do
_compskip=default
"$i" && ret=0
@@ -111,7 +117,7 @@
fi
[[ "$name" = -default- && -n "$comp" && "$_compskip" != (all|*default*) ]] &&
- "$comp" && ret=0
+ service="${_services[-default-]:--default-}" && "$comp" && ret=0
_compskip=''
diff -u -r ../oz/Completion/Core/compdump ./Completion/Core/compdump
--- ../oz/Completion/Core/compdump Wed Oct 11 16:23:16 2000
+++ ./Completion/Core/compdump Wed Oct 11 22:16:30 2000
@@ -35,12 +35,19 @@
print "#files: $#_d_files" > $_d_file
-# First dump the arrays _comps and _patcomps. The quoting hieroglyphyics
-# ensure that a single quote inside a variable is itself correctly quoted.
+# First dump the arrays _comps, _services and _patcomps. The quoting
+# hieroglyphyics ensure that a single quote inside a variable is itself
+# correctly quoted.
print "_comps=(" >> $_d_file
for _d_f in ${(ok)_comps}; do
print -r - "${(q)_d_f}" "${(q)_comps[$_d_f]}"
+done >> $_d_file
+print ")" >> $_d_file
+
+print "_services=(" >> $_d_file
+for _d_f in ${(ok)_services}; do
+ print -r - "${(q)_d_f}" "${(q)_services[$_d_f]}"
done >> $_d_file
print ")" >> $_d_file
diff -u -r ../oz/Completion/Core/compinit ./Completion/Core/compinit
--- ../oz/Completion/Core/compinit Wed Oct 11 16:23:16 2000
+++ ./Completion/Core/compinit Wed Oct 11 22:48:24 2000
@@ -100,12 +100,13 @@
esac
done
-# The associative array containing the definitions for the commands.
+# The associative array containing the definitions for the commands and
+# services.
# Definitions for patterns will be stored in the associations `_patcomps'
# and `_postpatcomps'. `_compautos' contains the names and options
# for autoloaded functions that get options.
-typeset -gA _comps _patcomps _postpatcomps _compautos
+typeset -gA _comps _services _patcomps _postpatcomps _compautos
# The associative array use to report information about the last
# cmpletion to the outside.
@@ -181,12 +182,12 @@
# delete the definitions for the command names `bar' and `baz'
compdef() {
- local opt autol type func delete new i
+ local opt autol type func delete new i ret=0 cmd svc
# Get the options.
if [[ $#* -eq 0 ]]; then
- echo "compdef needs parameters"
+ echo "$0: I needs arguments"
return 1
fi
@@ -216,11 +217,38 @@
shift OPTIND-1
if [[ $#* -eq 0 ]]; then
- echo "compdef needs parameters"
+ echo "$0: I needs arguments"
return 1
fi
if [[ -z "$delete" ]]; then
+ # If the first word contains an equal sign, all words must contain one
+ # and we define which services to use for the commands.
+
+ if [[ "$1" = *\=* ]]; then
+ for i; do
+ if [[ "$i" = *\=* ]]; then
+ cmd="${i%%\=*}"
+ svc="${i#*\=}"
+ func="$_comps[${(k)_services[(R)$svc]:-$svc}]"
+ [[ -z "$func" ]] &&
+ func="${_patcomps[(K)$svc][1]:-${_postpatcomps[(K)$svc][1]}}"
+ if [[ -n "$func" ]]; then
+ _comps[$cmd]="$func"
+ _services[$cmd]="$svc"
+ else
+ echo "$0: unknown command or service: $svc"
+ ret=1
+ fi
+ else
+ echo "$0: invalid argument: $i"
+ ret=1
+ fi
+ done
+
+ return ret
+ fi
+
# Adding definitions, first get the name of the function name
# and probably do autoloading.
@@ -290,15 +318,19 @@
*)
# For commands store the function name in the `_comps'
# associative array, command names as keys.
- if [[ -z "$new" ]]; then
- for i; do
- _comps[$i]="$func"
- done
- else
- for i; do
- [[ "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func"
- done
- fi
+ for i; do
+ if [[ "$i" = *\=* ]]; then
+ cmd="${i%%\=*}"
+ svc=yes
+ else
+ cmd="$i"
+ svc=
+ fi
+ if [[ -z "$new" || "${+_comps[$i]}" -eq 0 ]]; then
+ _comps[$cmd]="$func"
+ [[ -n "$svc" ]] && _services[$cmd]="${i#*\=}"
+ fi
+ done
;;
esac
else
@@ -314,7 +346,7 @@
# Oops, cannot do that yet.
echo "$0: cannot restore key bindings"
- return 1
+ return 1v
;;
*)
unset "_comps[$^@]"
diff -u -r ../oz/Completion/Debian/_apt ./Completion/Debian/_apt
--- ../oz/Completion/Debian/_apt Wed Oct 11 16:23:19 2000
+++ ./Completion/Debian/_apt Wed Oct 11 21:57:25 2000
@@ -1,12 +1,12 @@
#compdef apt-get apt-cache apt-cdrom apt-config
_apt () {
- case "${words[1]:t}" in
+ case "$service" in
apt-get) _apt-get "$@";;
apt-cache) _apt-cache "$@";;
apt-cdrom) _apt-cdrom "$@";;
apt-config) _apt-config "$@";;
- *) _message "unknown command $words[1]";;
+ *) _message "unknown command $service";;
esac
}
diff -u -r ../oz/Completion/Debian/_bug ./Completion/Debian/_bug
--- ../oz/Completion/Debian/_bug Wed Oct 11 16:23:19 2000
+++ ./Completion/Debian/_bug Wed Oct 11 21:57:41 2000
@@ -8,7 +8,7 @@
'-v[version]' \
'*:package:_deb_packages installed')
-case "${words[1]:t}" in
+case "$service" in
bug)
_arguments '-c[exclude configs from report]' \
'-f[argument is a file, not a package]' \
diff -u -r ../oz/Completion/Debian/_dpkg ./Completion/Debian/_dpkg
--- ../oz/Completion/Debian/_dpkg Wed Oct 11 16:23:19 2000
+++ ./Completion/Debian/_dpkg Wed Oct 11 21:57:58 2000
@@ -86,7 +86,7 @@
# _dpkg_actions_install=('(--install)-i[install]' '(-i)--install')
# _dpkg_actions_record_avail=('(--record-avail)-A[record available]' '(-A)--record-avail')
-case "${words[1]:t}" in
+case "$service" in
dpkg)
_arguments -C -s "$_dpkg_actions[@]" \
"$_dpkg_deb_actions[@]" \
diff -u -r ../oz/Completion/User/_bzip2 ./Completion/User/_bzip2
--- ../oz/Completion/User/_bzip2 Wed Oct 11 16:23:21 2000
+++ ./Completion/User/_bzip2 Wed Oct 11 21:58:50 2000
@@ -1,12 +1,12 @@
-#compdef bzip2 bzcat bunzip2 bzip2recover
+#compdef bzip2 bunzip2 bzcat=bunzip2 bzip2recover
local decompress expl state line curcontext="$curcontext"
typeset -A opt_args
-case "${words[1]:t}" in
+case "$service" in
bzip2recover) [[ $CURRENT = 2 ]] && state=files;;
bzip2) decompress=no;&
- bunzip2|bzcat) _arguments -C -s \
+ bunzip2) _arguments -C -s \
'(--help)-h[display help message]' \
'(-h)--help[display help message]' \
'(--decompress --compress -z --test -t)-d[decompress]' \
diff -u -r ../oz/Completion/User/_chown ./Completion/User/_chown
--- ../oz/Completion/User/_chown Wed Oct 11 16:23:21 2000
+++ ./Completion/User/_chown Wed Oct 11 21:59:10 2000
@@ -3,7 +3,7 @@
local suf
if [[ CURRENT -eq 2 || CURRENT -eq 3 && $words[CURRENT-1] = -* ]]; then
- if [[ ${words[1]:t} = chgrp ]] || compset -P '*[:.]'; then
+ if [[ $service = chgrp ]] || compset -P '*[:.]'; then
_groups
else
if [[ $OSTYPE = (solaris*|hpux*) ]]; then
diff -u -r ../oz/Completion/User/_compress ./Completion/User/_compress
--- ../oz/Completion/User/_compress Wed Oct 11 16:23:21 2000
+++ ./Completion/User/_compress Wed Oct 11 21:59:38 2000
@@ -17,7 +17,7 @@
'(-q)-v[display compression statistics]' \
"${common_args1[@]}" )
-case "${words[1]:t}" in
+case "$service" in
compress)
_arguments -C -s \
"-b[specify maximum number of bits used to replace common substring]:bits:(${bits[*]})" \
diff -u -r ../oz/Completion/User/_dvi ./Completion/User/_dvi
--- ../oz/Completion/User/_dvi Wed Oct 11 16:23:21 2000
+++ ./Completion/User/_dvi Wed Oct 11 22:00:21 2000
@@ -9,7 +9,7 @@
':output DVI file:_files -g \*.\(dvi\|DVI\)'
)
-case "${words[1]:t}" in
+case "$service" in
dvips)
_arguments -s \
'-a[make three passes]' \
diff -u -r ../oz/Completion/User/_gzip ./Completion/User/_gzip
--- ../oz/Completion/User/_gzip Wed Oct 11 16:23:22 2000
+++ ./Completion/User/_gzip Wed Oct 11 22:01:07 2000
@@ -1,10 +1,10 @@
-#compdef gzip gunzip gzcat
+#compdef gzip gunzip gzcat=gunzip
local decompress expl curcontext="$curcontext" state line
typeset -A opt_args
-case "${words[1]:t}" in
-gunzip|zcat|gzcat)
+case "$service" in
+gunzip)
decompress=yes
;&
gzip)
diff -u -r ../oz/Completion/User/_imagemagick ./Completion/User/_imagemagick
--- ../oz/Completion/User/_imagemagick Wed Oct 11 16:23:20 2000
+++ ./Completion/User/_imagemagick Wed Oct 11 21:56:14 2000
@@ -18,7 +18,7 @@
return
fi
-case "${words[1]:t}" in
+case "$service" in
display)
_arguments -M 'm:{a-z}={A-Z}' \
'*-backdrop[use full screen]' \
diff -u -r ../oz/Completion/User/_ispell ./Completion/User/_ispell
--- ../oz/Completion/User/_ispell Wed Oct 11 16:23:22 2000
+++ ./Completion/User/_ispell Wed Oct 11 22:01:32 2000
@@ -1,6 +1,6 @@
#compdef ispell buildhash munchlist findaffix tryaffix icombine ijoin
-case "${words[1]:t}" in
+case "$service" in
ispell)
_arguments -s \
'(-n -h)-t[input file is in TeX/LaTeX format]' \
diff -u -r ../oz/Completion/User/_java ./Completion/User/_java
--- ../oz/Completion/User/_java Wed Oct 11 16:23:24 2000
+++ ./Completion/User/_java Wed Oct 11 22:02:29 2000
@@ -6,7 +6,7 @@
jdb_args=()
-case "${words[1]:t}" in
+case "$service" in
javac)
_arguments \
'-g-[generate debugging information]:debug:->debug' \
diff -u -r ../oz/Completion/User/_lp ./Completion/User/_lp
--- ../oz/Completion/User/_lp Wed Oct 11 16:23:22 2000
+++ ./Completion/User/_lp Wed Oct 11 22:03:49 2000
@@ -5,7 +5,7 @@
if compset -P -P || [[ "$words[CURRENT-1]" = -P ]]; then
_printers
else
- if [[ "${words[1]:t}" = (lpq|lprm) ]]; then
+ if [[ "$service" = (lpq|lprm) ]]; then
if [[ "$words" = *-P* ]]; then
printer=(-P "${${words##*-P( |)}%% *}")
else
diff -u -r ../oz/Completion/User/_mount ./Completion/User/_mount
--- ../oz/Completion/User/_mount Wed Oct 11 16:23:22 2000
+++ ./Completion/User/_mount Wed Oct 11 22:05:32 2000
@@ -368,7 +368,7 @@
esac
fi
-if [[ "${words[1]:t}" = mount ]]; then
+if [[ "$service" = mount ]]; then
# Here are the tests and tables for the arguments and options for
# the `mount' program. The `fss' array has to be set to the names
diff -u -r ../oz/Completion/User/_mysql_utils ./Completion/User/_mysql_utils
--- ../oz/Completion/User/_mysql_utils Wed Oct 11 16:23:23 2000
+++ ./Completion/User/_mysql_utils Wed Oct 11 22:06:23 2000
@@ -224,7 +224,7 @@
}
_mysql_utils () {
- case "${words[1]:t}" in
+ case "$service" in
mysql)
_mysql "$@"
;;
diff -u -r ../oz/Completion/User/_pack ./Completion/User/_pack
--- ../oz/Completion/User/_pack Wed Oct 11 16:23:23 2000
+++ ./Completion/User/_pack Wed Oct 11 22:06:55 2000
@@ -1,15 +1,15 @@
-#compdef pack pcat unpack
+#compdef pack unpack pcat=unpack
local expl state line
-case ${words[1]:t} in
+case $service in
pack)
_arguments -C \
'-f[force packing even for files which will not benefit]' \
'-[show statistics for files]' \
'*:file to compress:_files -g \*\~\*.z'
;;
- pcat|unpack)
+ unpack)
_description files expl 'compressed file'
_files "$expl[@]" -g '*.z'
;;
diff -u -r ../oz/Completion/User/_pbm ./Completion/User/_pbm
--- ../oz/Completion/User/_pbm Wed Oct 11 16:23:23 2000
+++ ./Completion/User/_pbm Wed Oct 11 21:55:27 2000
@@ -6,14 +6,14 @@
# defaults can be overridden by simply defining completion functions
# for those commands whose arguments you want to complete differently.
-local pat expl ret=1 cmd="${words[1]:t}"
+local pat expl ret=1
-if [[ "$cmd" = pnm* ]]; then
+if [[ "$service" = pnm* ]]; then
pat='*.(#i)p[bgp]m'
-elif [[ "$cmd" = *top[bgpn]m ]]; then
- pat="*.(#i)${cmd%%top[bgpn]m}"
+elif [[ "$service" = *top[bgpn]m ]]; then
+ pat="*.(#i)${service%%top[bgpn]m}"
else
- pat="*.(#i)${cmd[1,3]}"
+ pat="*.(#i)${service[1,3]}"
fi
if [[ $# -ne 0 || $+_in_pbm -ne 0 ]]; then
@@ -24,7 +24,7 @@
local _in_pbm=yes
-case "$cmd" in
+case "$service" in
asciitop[gn]m)
_arguments \
'-d[specify divisor]:divisor:' \
diff -u -r ../oz/Completion/User/_psutils ./Completion/User/_psutils
--- ../oz/Completion/User/_psutils Wed Oct 11 16:23:24 2000
+++ ./Completion/User/_psutils Wed Oct 11 22:11:29 2000
@@ -1,6 +1,6 @@
#compdef epsffit extractres fixdlsrps fixfmps fixmacps fixpsditps fixpspps fixscribeps fixtpps fixwfwps fixwpps fixwwps includeres psbook psmerge psnup psresize psselect pstops getafm showchar
-case "${words[1]:t}" in
+case "$service" in
epsffit)
_arguments \
'-v[print version]' \
diff -u -r ../oz/Completion/User/_rcs ./Completion/User/_rcs
--- ../oz/Completion/User/_rcs Wed Oct 11 16:23:24 2000
+++ ./Completion/User/_rcs Wed Oct 11 22:12:11 2000
@@ -1,10 +1,10 @@
#compdef co ci rcs
-local nm=$compstate[nmatches] cmd="${words[1]:t}"
+local nm=$compstate[nmatches]
-[[ $cmd = ci || $cmd = rcs ]] && _files
+[[ $service = ci || $service = rcs ]] && _files
-if [[ $compstate[nmatches] -eq nm && -d RCS && $cmd != ci ]]; then
+if [[ $compstate[nmatches] -eq nm && -d RCS && $service != ci ]]; then
local rep expl
rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
diff -u -r ../oz/Completion/User/_rlogin ./Completion/User/_rlogin
--- ../oz/Completion/User/_rlogin Wed Oct 11 16:23:24 2000
+++ ./Completion/User/_rlogin Wed Oct 11 21:52:09 2000
@@ -1,7 +1,7 @@
-#compdef rlogin rsh remsh rcp
+#compdef rlogin rsh remsh=rsh rcp
_rlogin () {
- case "${words[1]:t}" in
+ case "$service" in
rlogin)
_arguments -s \
'-8[allow 8-Bit data]' \
diff -u -r ../oz/Completion/User/_ssh ./Completion/User/_ssh
--- ../oz/Completion/User/_ssh Wed Oct 11 16:23:24 2000
+++ ./Completion/User/_ssh Wed Oct 11 21:51:32 2000
@@ -1,4 +1,4 @@
-#compdef ssh slogin scp ssh-add ssh-agent ssh-keygen
+#compdef ssh slogin=ssh scp ssh-add ssh-agent ssh-keygen
_remote_files () {
# This is extremely simple-minded; could parse "ls -F" output to do
@@ -14,8 +14,8 @@
# ssh-opt is a pseudo-command used to complete ssh options for `scp -o'.
- case "${words[1]:t}" in
- ssh|slogin)
+ case "$service" in
+ ssh)
args=(
':remote host name:->userhost'
'(-):command: _command_names -e'
@@ -179,6 +179,7 @@
compset -q
words=(ssh-opt "$words[@]" )
(( CURRENT++ ))
+ service=ssh-opt
_ssh
return
elif [[ -n "$state" ]]; then
diff -u -r ../oz/Completion/User/_tiff ./Completion/User/_tiff
--- ../oz/Completion/User/_tiff Wed Oct 11 16:23:25 2000
+++ ./Completion/User/_tiff Wed Oct 11 21:55:48 2000
@@ -1,9 +1,9 @@
#compdef -P (tiff*|*2tiff|pal2rgb)
-local pat expl ret=1 cmd="${words[1]:t}"
+local pat expl ret=1
-if [[ "$cmd" = *2tiff ]]; then
- pat="*.(#i)${cmd%%2tiff}"
+if [[ "$service" = *2tiff ]]; then
+ pat="*.(#i)${service}"
else
pat="*.(#i)tiff"
fi
@@ -23,7 +23,7 @@
local curcontext="$curcontext" state line ret=1
typeset -A opt_args
-case "$cmd" in
+case "$service" in
tiff2bw)
_arguments -C \
'-c[specify compression scheme]:compression scheme:->compress' \
diff -u -r ../oz/Completion/User/_yp ./Completion/User/_yp
--- ../oz/Completion/User/_yp Wed Oct 11 16:23:26 2000
+++ ./Completion/User/_yp Wed Oct 11 22:12:33 2000
@@ -14,7 +14,7 @@
)
fi
-case "${words[1]:t}" in
+case "$service" in
ypcat)
_arguments -C -s "$_yp_args[@]" ':map name:->map' && ret=0
;;
diff -u -r ../oz/Completion/X/_xutils ./Completion/X/_xutils
--- ../oz/Completion/X/_xutils Wed Oct 11 16:23:29 2000
+++ ./Completion/X/_xutils Wed Oct 11 22:12:49 2000
@@ -1,6 +1,6 @@
#compdef xdpyinfo xwininfo xkill xfontsel xfd xev xhost xon xsetroot xwd xwud xrdb
-case "${words[1]:t}" in
+case "$service" in
xdpyinfo)
_x_arguments \
-queryExtensions \
diff -u -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo
--- ../oz/Doc/Zsh/compsys.yo Wed Oct 11 16:23:42 2000
+++ ./Doc/Zsh/compsys.yo Wed Oct 11 23:04:27 2000
@@ -164,6 +164,14 @@
either the name of a command whose arguments are to be completed or one of
a number of special contexts in the form tt(-)var(context)tt(-) described
below for the tt(_complete) function.
+
+Each var(name) may also be of the form `var(cmd)tt(=)var(service)'. This
+is used by functions that offer multiple services, i.e. different
+completion behaviour for multiple commands. Such a string
+makes the completion system call the function when completing
+arguments for the command `tt(cmd)', setting the parameter tt($service)
+to the string `tt(service)'. The function can then use that parameter
+to decide what to complete.
)
item(tt(#compdef -p) var(pattern))(
The file will be made autoloadable and the function defined in it will be
@@ -253,7 +261,15 @@
item(tt(compdef -K) [ tt(-an) ] var(function name style key-sequences ...))(
The first form tells the completion system to call the given
var(function) when completing for the contexts or commands
-whose var(names) are given: this is like the tt(#compdef) tag. If the
+whose var(names) are given: this is like the tt(#compdef) tag unless
+the first word contains an equal sign. In this case all words have to
+be of the form `var(cmd)tt(=)var(service)' where var(service) is the
+name of a command or of a service defined by an autoloaded function
+with the tt(#compdef) tag and an argument of the form
+`var(cmd)tt(=)var(service)'. This kind of use makes the arguments of
+the var(cmd)s be completed as those for the var(services).
+
+If the
tt(-n) option is given, any existing completion behaviour for particular
contexts or commands will not be altered. These definitions can be deleted
by giving the tt(-d) option as in the second form.
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2000-10-12 9:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-10-11 7:32 multiple-commands-functions Sven Wischnowsky
2000-10-11 14:46 ` multiple-commands-functions Bart Schaefer
2000-10-11 14:56 multiple-commands-functions Sven Wischnowsky
2000-10-12 9:12 multiple-commands-functions Sven Wischnowsky
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).