diff options
Diffstat (limited to 'Completion')
-rw-r--r-- | Completion/User/_combination | 85 | ||||
-rw-r--r-- | Completion/User/_ports | 8 | ||||
-rw-r--r-- | Completion/User/_socket | 14 | ||||
-rw-r--r-- | Completion/User/_telnet | 38 |
4 files changed, 129 insertions, 16 deletions
diff --git a/Completion/User/_combination b/Completion/User/_combination new file mode 100644 index 000000000..a122bd86f --- /dev/null +++ b/Completion/User/_combination @@ -0,0 +1,85 @@ +#autoload + +# Usage: +# _combination [-s SEP] VARIABLE KEYi=PATi KEYj=PATj ... KEYm=PATm KEY EXPL... +# +# VARIABLE must be formd as PREFIX_KEY1_..._KEYn. +# +# Example: telnet +# +# Assume an user sets the variable `telnet_hosts_ports_users' as: +# +# telnet_hosts_ports_users=( +# host0:: host1::user1 host2::user2 +# mail-server:{smtp,pop3}: +# news-server:nntp: +# proxy-server:8000: +# ) +# +# `_telnet completes' hosts as: +# +# _combination telnet_hosts_ports_users \ +# ${options[-l]:+users=${options[-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 telnet_hosts_ports_users \ +# ${options[-l]:+users=${options[-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 telnet_hosts_ports_users \ +# ${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 var keys pats key tmp + +if [[ "$1" = -s ]]; then + sep="$2" + shift 2 +else + sep=: +fi + +var=$1 +shift + +keys=( "${(@s:_:)${var#*_}}" ) +pats=( "${(@)keys/*/*}" ) + +while [[ "$1" = *=* ]]; do + pats[$keys[(i)${1%%\=*}]]="${1#*\=}" + shift +done + +key="$1" +shift + +if (( ${(P)+${var}} )); then + eval "tmp=( \"\${(@M)${var}:#\${(j!$sep!)~pats}}\" )" + if (( keys[(i)$key] != 1 )); then + eval "tmp=( \${tmp#\${(j!${sep}!)~\${(@)\${(@)keys[2,(r)\$key]}/*/*}}$sep} )" + fi + tmp=( ${tmp%%$sep*} ) + + compadd "$@" - $tmp || { builtin functions _$key >&- && _$key "$@" } +else + builtin functions _$key >&- && _$key "$@" +fi + diff --git a/Completion/User/_ports b/Completion/User/_ports new file mode 100644 index 000000000..950212832 --- /dev/null +++ b/Completion/User/_ports @@ -0,0 +1,8 @@ +#autoload + +local expl + +: ${(A)ports:=${${(M)${${(f)"$(</etc/services)"}:#\#*}#*/tcp}%%[ ]*}} + +_description expl port +compadd "$@" "$expl[@]" - "$ports[@]" diff --git a/Completion/User/_socket b/Completion/User/_socket index c7605a1ac..ff8009ea1 100644 --- a/Completion/User/_socket +++ b/Completion/User/_socket @@ -2,10 +2,8 @@ # Parameter used: # -# socket_ports -# The associative array that maps a host name to a space-separated list of -# ports. - +# socket_hosts_ports +# The array that contains paris `host:port'. local state line expl typeset -A options @@ -28,18 +26,14 @@ arg1) _message 'port to listen' else _description expl 'host' - compadd "$expl[@]" - ${(k)socket_ports} || _hosts "$expl[@]" + _combination socket_hosts_ports hosts "$expl[@]" fi ;; arg2) if (( ! $+options[-s] )); then _description expl 'port to connect' - if (( $+socket_ports )); then - compadd "$expl[@]" - ${=socket_ports[$line[2]]}; - else - _message 'port to connect'; - fi + _combination socket_hosts_ports hosts="${line[2]:q}" ports "$expl[@]" fi ;; esac diff --git a/Completion/User/_telnet b/Completion/User/_telnet index 594dcf2e5..82fd6b21c 100644 --- a/Completion/User/_telnet +++ b/Completion/User/_telnet @@ -2,9 +2,11 @@ # Parameter used: # -# telnet_ports -# The associative array that maps a host name to a space-separated list of -# ports. +# telnet_hosts_ports_users +# The array that contains 3-tuples `host:port:user'. + +local state line expl +typeset -A options _arguments -s \ -{F,f,x} \ @@ -19,9 +21,33 @@ _arguments -s \ '-d[debug mode]' \ '-e+[specify escape character]:escape character:' \ '-k+:realm:' \ - '-l+[specify user]:user:' \ + '-l+[specify user]:user:->users' \ '-n+[specify tracefile]:tracefile:_files' \ '-r[rlogin like user interface]' \ - ':host:{ compadd "$expl[@]" - ${(k)telnet_ports} || _hosts "$expl[@]" }' \ - ':port:{ if (( $+telnet_ports )); then compadd "$expl[@]" - ${=telnet_ports[$line[2]]}; else _message "port"; fi }' + ':host:->hosts' \ + ':port:->ports' + +case "$state" in +hosts) + _description expl 'host' + _combination telnet_hosts_ports_users \ + ${options[-l]:+users=${options[-l]:q}} \ + hosts "$expl[@]" + ;; + +ports) + _description expl 'port' + _combination telnet_hosts_ports_users \ + ${options[-l]:+users=${options[-l]:q}} \ + hosts="${line[2]:q}" \ + ports "$expl[@]" + ;; +users) + _description expl 'user' + _combination telnet_hosts_ports_users \ + ${line[2]:+hosts="${line[2]:q}"} \ + ${line[3]:+ports="${line[3]:q}"} \ + users "$expl[@]" + ;; +esac |