diff options
Diffstat (limited to 'Completion/Base/Utility')
-rw-r--r-- | Completion/Base/Utility/_combination | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/Completion/Base/Utility/_combination b/Completion/Base/Utility/_combination new file mode 100644 index 000000000..dcb3269cd --- /dev/null +++ b/Completion/Base/Utility/_combination @@ -0,0 +1,94 @@ +#autoload + +# Usage: +# _combination [-s S] TAG STYLE \ +# Ki1[:Ni1]=Pi1 Ki2[:Ni2]=Pi2 ... Kim[:Nim]=Pim Kj[:Nj] EXPL... +# +# STYLE should be of the form K1-K2-...-Kn. +# +# Example: telnet +# +# Assume an user sets the style `users-hosts-ports' as for the my-accounts +# tag: +# +# zstyle ':completion:*:*:telnet:*:my-accounts' users-hosts-ports \ +# @host0: user1@host1: user2@host2: +# @mail-server:{smtp,pop3} +# @news-server:nntp +# @proxy-server:8000 +# +# +# `_telnet' completes hosts as: +# +# _combination my-accounts users-hosts-ports \ +# ${opt_args[-l]:+users=${opt_args[-l]:q}} \ +# hosts "$expl[@]" +# +# This completes `host1', `host2', `mail-server', `news-server' and +# `proxy-server' according to the user given with `-l' if it is exists. +# And if it is failed, `_hosts' is called. +# +# `_telnet' completes ports as: +# +# _combination my-accounts users-hosts-ports \ +# ${opt_args[-l]:+users=${opt_args[-l]:q}} \ +# hosts="${line[2]:q}" \ +# ports "$expl[@]" +# +# This completes `smtp', `pop3', `nntp' and `8000' according to the +# host argument --- $line[2] and the user option argument if it is +# exists. And if it is failed, `_ports' is called. +# +# `_telnet' completes users for an argument of option `-l' as: +# +# _combination my-accounts users-hosts-ports \ +# ${line[2]:+hosts="${line[2]:q}"} \ +# ${line[3]:+ports="${line[3]:q}"} \ +# users "$expl[@]" +# +# This completes `user1' and `user2' according to the host argument and +# the port argument if they are exist. And if it is failed, `_users' is +# called. + +local sep tag style keys pats key num tmp + +if [[ "$1" = -s ]]; then + sep="$2" + shift 2 +elif [[ "$1" = -s* ]]; then + sep="${1[3,-1]}" + shift +else + sep=: +fi + +tag="$1" +style="$2" +shift 2 + +keys=( ${(s/-/)style} ) +pats=( "${(@)keys/*/*}" ) + +while [[ "$1" = *=* ]]; do + tmp="${1%%\=*}" + key="${tmp%:*}" + num="${${tmp##*:}:-1}" + pats[$keys[(in:num:)$key]]="${1#*\=}" + shift +done + +key="${1%:*}" +num="${${1##*:}:-1}" +shift + +if zstyle -a ":completion:${curcontext}:$tag" "$style" tmp; then + eval "tmp=( \"\${(@M)tmp:#\${(j($sep))~pats}}\" )" + if (( keys[(in:num:)$key] != 1 )); then + eval "tmp=( \${tmp#\${(j(${sep}))~\${(@)\${(@)keys[2,(rn:num:)\$key]}/*/*}}${~sep}} )" + fi + tmp=( ${tmp%%${~sep}*} ) + + compadd "$@" -a tmp || { (( $+functions[_$key] )) && "_$key" "$@" } +else + (( $+functions[_$key] )) && "_$key" "$@" +fi |