about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Completion/User/_combination85
-rw-r--r--Completion/User/_ports8
2 files changed, 93 insertions, 0 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[@]"